-
Notifications
You must be signed in to change notification settings - Fork 826
List.fold/contains simplification #3975
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
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 |
---|---|---|
|
@@ -212,15 +212,11 @@ namespace Microsoft.FSharp.Collections | |
|
||
[<CompiledName("Fold")>] | ||
let fold<'T,'State> folder (state:'State) (list: 'T list) = | ||
match list with | ||
| [] -> state | ||
| _ -> | ||
let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(folder) | ||
let rec loop s xs = | ||
match xs with | ||
| [] -> s | ||
| h::t -> loop (f.Invoke(s,h)) t | ||
loop state list | ||
let f = OptimizedClosures.FSharpFunc<_,_,_>.Adapt(folder) | ||
let mutable acc = state | ||
for x in list do | ||
acc <- f.Invoke(acc, x) | ||
acc | ||
|
||
[<CompiledName("Pairwise")>] | ||
let pairwise (list: 'T list) = | ||
|
@@ -356,12 +352,10 @@ namespace Microsoft.FSharp.Collections | |
let exists predicate list = Microsoft.FSharp.Primitives.Basics.List.exists predicate list | ||
|
||
[<CompiledName("Contains")>] | ||
let inline contains value source = | ||
let rec contains e xs1 = | ||
match xs1 with | ||
| [] -> false | ||
| h1::t1 -> e = h1 || contains e t1 | ||
contains value source | ||
let rec contains value source = | ||
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. Does it matter that 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. @isaacabraham idk, but neither are 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. Hmmm - so why was 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. People started to inline stuff in other PRs... 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. Yes, the "inline" matters a lot. The inlining causes the equality check to become monomorphic (non-generic) in the common case that the callsite is monmorphic, and hence the equality check will be type-specialized 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. @dsyme I'll take it out if the inline is that important, as I'm not sure how to get around FS1118 (cannot inline recursive). 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. Yes, the nested Was the use of a nested 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. @dsyme Nothing to do with Fable, this optimization was just to remove the unnecessary extra object allocation and call that is generated, but I understand the inline modifier is more important here (although there are other funcs with 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.
If there is performance evidence to show that it's worthwhile inlining these then we should likely do it. Normally it's easy to get perf evidence in such cases. Sometimes the inlining can't be done due to the implementation depending on other internal functions we don't want to make public |
||
match source with | ||
| [] -> false | ||
| h::t -> if h = value then true else contains value t | ||
|
||
let rec exists2aux (f:OptimizedClosures.FSharpFunc<_,_,_>) list1 list2 = | ||
match list1,list2 with | ||
|
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.
This optimization for the case where the list is empty has been removed - can it please be added back in? Or lets just not do this change
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.
@dsyme Thanks, I'll add it. The optimization for the empty case is still there to some extent, in the sense that the folding function is not being called in the "empty list" case. But yes, additional check in the beginning for the empty case makes a lot of sense, so the Adapt function is not called prematurely. I'll resubmit.
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.
Thanks. I integrated the revert so you can submit a new PR at your leisure :) thanks all!