Skip to content

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

Merged
merged 1 commit into from
Nov 20, 2017
Merged

List.fold/contains simplification #3975

merged 1 commit into from
Nov 20, 2017

Conversation

ncave
Copy link
Contributor

@ncave ncave commented Nov 19, 2017

Generates simpler IL.

@ncave ncave changed the title minor IL simplification List.fold/contains simplification Nov 19, 2017
Copy link
Contributor

@KevinRansom KevinRansom left a 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 =
Copy link
Contributor

@isaacabraham isaacabraham Nov 19, 2017

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor

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...

Copy link
Contributor

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

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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).

Copy link
Contributor

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

@KevinRansom KevinRansom merged commit d8544fe into dotnet:master Nov 20, 2017
@KevinRansom
Copy link
Contributor

Thank you for this.

@dsyme
Copy link
Contributor

dsyme commented Nov 20, 2017

@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 inline but I haven't looked at that yet - the first issue is enough to mean that it shouldn't be integrated.

@@ -212,15 +212,11 @@ namespace Microsoft.FSharp.Collections

[<CompiledName("Fold")>]
let fold<'T,'State> folder (state:'State) (list: 'T list) =
match list with
| [] -> state
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

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!

Copy link
Contributor

@dsyme dsyme left a 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 added a commit that referenced this pull request Nov 20, 2017
@vasily-kirichenko
Copy link
Contributor

@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")

@dsyme
Copy link
Contributor

dsyme commented Nov 20, 2017

  • Let's all strive for high standard reviews
  • I try to review everything except Visual F# IDE Tooling specific things which I just glance at. Assign me as a reviewer and @dsyme me if needed - after a weekend I tend to search for those first
  • PRs should come with explanations, thanks

dsyme added a commit that referenced this pull request Nov 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants