-
Notifications
You must be signed in to change notification settings - Fork 362
List module performance improvements #1027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a017feb
199e7d9
3e877b5
c9975bf
b97247c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,7 +132,17 @@ element (starting at zero). | |
| -} | ||
| indexedMap : (Int -> a -> b) -> List a -> List b | ||
| indexedMap f xs = | ||
| map2 f (range 0 (length xs - 1)) xs | ||
| reverse (indexedMapHelper f 0 xs []) | ||
|
|
||
|
|
||
| indexedMapHelper : (Int -> a -> b) -> Int -> List a -> List b -> List b | ||
| indexedMapHelper fn index list result = | ||
| case list of | ||
| [] -> | ||
| result | ||
|
|
||
| x :: xs -> | ||
| indexedMapHelper fn (index + 1) xs (cons (fn index x) result) | ||
|
|
||
|
|
||
| {-| Reduce a list from the left. | ||
|
|
@@ -198,7 +208,7 @@ foldrHelper fn acc ctr ls = | |
| d :: r4 -> | ||
| let | ||
| res = | ||
| if ctr > 500 then | ||
| if ctr > 1000 then | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder why did you change this magic number but I assume some measurements suggested to do so.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It’s to match the similar number for take. The number should be as big as possible, without risking that people run into stack overflows. Since take has had the number at 1000 for a long while now, and people don’t complain about stack overflows, it seemed sensible to increase it for foldr as well. |
||
| foldl fn acc (reverse r4) | ||
| else | ||
| foldrHelper fn acc (ctr + 1) r4 | ||
|
|
@@ -227,17 +237,16 @@ from an untrusted source and you want to turn them into numbers: | |
| -} | ||
| filterMap : (a -> Maybe b) -> List a -> List b | ||
| filterMap f xs = | ||
| foldr (maybeCons f) [] xs | ||
|
|
||
|
|
||
| maybeCons : (a -> Maybe b) -> a -> List b -> List b | ||
| maybeCons f mx xs = | ||
| case f mx of | ||
| Just x -> | ||
| cons x xs | ||
| let | ||
| helper mx acc = | ||
| case f mx of | ||
| Just x -> | ||
| cons x acc | ||
|
|
||
| Nothing -> | ||
| xs | ||
| Nothing -> | ||
| acc | ||
| in | ||
| foldr helper [] xs | ||
|
|
||
|
|
||
| -- UTILITIES | ||
|
|
@@ -363,13 +372,8 @@ product numbers = | |
| You can also use [the `(++)` operator](Basics#++) to append lists. | ||
| -} | ||
| append : List a -> List a -> List a | ||
| append xs ys = | ||
| case ys of | ||
| [] -> | ||
| xs | ||
|
|
||
| _ -> | ||
| foldr cons ys xs | ||
| append = | ||
| Elm.Kernel.List.append | ||
|
|
||
|
|
||
| {-| Concatenate a bunch of lists into a single list: | ||
|
|
@@ -387,7 +391,12 @@ concat lists = | |
| -} | ||
| concatMap : (a -> List b) -> List a -> List b | ||
| concatMap f list = | ||
| concat (map f list) | ||
| let | ||
| helper val acc = | ||
| append (f val) acc | ||
| in | ||
| foldr helper [] list | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sparksp figured out a faster fasterConcatMap : (a -> List b) -> List a -> List b
fasterConcatMap f =
List.foldr (f >> (++)) []Granted, this doesn't take the JS changes into account, so maybe overall your version is faster, but in current There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Luckily this is the same as the proposed concatMap 😄
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. beware:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The JS changes in this PR makes
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exactly. The point of this PR is to make the non-obvious performance difference between I wonder if you have any idea how @evancz feels about the change @Skinney. It's been a while since this was opened.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember that me and Evan looked through this, but I forget what the conclusion of that meeting was. I don't think he was opposed to any of the changes, though. |
||
|
|
||
|
|
||
|
|
||
| {-| Places the given value between all members of the given list. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick - I wonder about naming here. For instance cons uses this convention
var _List_cons = F2(_List_Cons);(note same naming but different cases)core/src/Elm/Kernel/List.js
Line 16 in 4fbcb15
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_List_Consis a constructor (the function returns a type)._List_consis a function, which calls the constructor. You’ll see it defined in theListmodule as a function.