-
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
Conversation
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.
Nice, thanks for this.
| [] -> 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Does it matter that contains
is no longer marked as inline
?
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.
@isaacabraham idk, but neither are exists
, find/findBack
, tryFind/tryFindBack
, pick/tryPick
etc.
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.
Hmmm - so why was contains
inlined? Just some historical artifact, or some reason.
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.
People started to inline stuff in other PRs...
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.
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 comment
The 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 are a few other funcs with when 'T : equality
signature (except, distinct, countBy etc.), should they be inline as well?
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.
Yes, the nested let rec
is to get around the restriction on let rec inline
. The whole inner let rec
gets copied that way.
Was the use of a nested let rec
causing problems for Fable? If so you may often be able to replace with an explicit loop
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 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 when 'T : equality
that are not inline).
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.
I understand the inline modifier is more important here (although there are other funcs with when 'T : equality that are not inline).
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
Thank you for this. |
@KevinRansom Please revert this, it needs proper review. And can we in general please look at changes a bit more deeply before integrating them? For example, it removes an optimization for empty lists here.https://github.com/Microsoft/visualfsharp/pull/3975/files#diff-9c7a3b0c1ddcc1a72b924ffac75f21feL215. Perhaps we can do this, but it needs performance testing and review. It also removes the use of |
@@ -212,15 +212,11 @@ namespace Microsoft.FSharp.Collections | |||
|
|||
[<CompiledName("Fold")>] | |||
let fold<'T,'State> folder (state:'State) (list: 'T list) = | |||
match list with | |||
| [] -> state |
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!
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.
As mentioned, please revert
@dsyme the problem is that we never know when (and if) you are going to review a PR. Is it possible to mark a PR as "must be reviewed by ....", with proper notification? (or "I'm gonna review this by the end of this week") |
|
Generates simpler IL.