-
Notifications
You must be signed in to change notification settings - Fork 789
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
Add List.chooseV, Seq.tryPickV, etc. for ValueOption #6781
Conversation
@cmeeren If possible, can you change this PR to a draft? That way it's clear that the PR is for experimentation and information about what this feature could mean. Once you're comfortable with a trial implementation, it would be great to spin up a few BenchmarkDotNet experiments that attempt to simulate common tasks. A subfolder containing a solution could be placed here: https://github.com/dotnet/fsharp/tree/master/tests/fsharp/perf This would help really suss out the impact from a CPU time and memory perspective of having these kinds of functions. |
I have never used BenchmarkDotNet and am quite busy with real-life events the next months, so I can't promise anything (I probably won't be able to delve into it). For the record though, what specifically do you want the tests to measure? Should they compare the Also, do you know where I can find |
@cartermp Are you able to provide some clarification on the questions in my last comment? |
@cmeeren Sorry for not getting back to you yet. Re: draft PR - this is fine. It's unfortunate that GitHub doesn't allow this. As for benchmarking, it's quite easy. I have an example here that demonstrates how you can measure CPU and memory usage for distinct things: https://github.com/cartermp/trees The idea is that you'd compare the built-in FSharp.Core methods today with your own variants written in a separate file/namepsace/module/etc. It would be good to have a few different benchmark classes:
That should give a pretty good view over the impact of using ValueOption for things. |
Thanks! I still need to know where I can find |
Choose is here: https://github.com/dotnet/fsharp/blob/master/src/fsharp/FSharp.Core/local.fs#L187 Unfold is here: https://github.com/dotnet/fsharp/blob/master/src/fsharp/FSharp.Core/local.fs#L781 Note that they ultimately rely on inline IL: https://github.com/dotnet/fsharp/blob/master/src/fsharp/FSharp.Core/local.fs#L96 So you'll have to do the benchmarks with a built FSharp.Core, otherwise your code will be at a disadvantage 🙂 |
@cartermp I'm working on perf tests, but having problems referencing the built FSharp.Core. I've added it in the project file: <ItemGroup>
<Reference Include="FSharp.Core">
<HintPath>..\..\..\..\..\artifacts\bin\FSharp.Core\Release\netstandard1.6\FSharp.Core.dll</HintPath>
</Reference>
</ItemGroup> However, I don't have access to the new functions, even though they appear in the corresponding Do you have any tips? |
You can look at @dsyme's PR here: #6811 A project file example is here: https://github.com/dotnet/fsharp/pull/6811/files#diff-49b750428326bdfe4736d158ea9d2f78R17 |
Apologies for my confusion, but that's a project reference, and you said I have to
Perhaps I misunderstood that remark? I figured it meant that I had to reference a pre-compiled DLL. Though, come to think of it, what's the difference - the project is compiled anyway, of course. So what did you mean? |
Sorry, what I meant was just an updated FSharp.Core. Project reference is likely the best way to do that. |
I've added performance tests now. Is it what you were after? Again, I've never used BenchmarkDotNet before, so please tell me if I should change anything. |
Can you paste the perf results here? Thanks |
Here are the benchmark results: choose(
tryPick(
I'm confused by the |
Likewise! The
thanks! |
@dsyme any reason choose is faster than chooseV for an int ? Is there a specific optimization in the rest of the compiler ? |
No. It could be a number of things - alignments, registers 22.47 ns is very short, perhaps run the operation many more times in a loop rather than relying on the benchmarking to do that. |
@dsyme I wouldn't expect much of a change there, as BenchmarkDotNet is running it enough times such that it's statistically sufficient. Putting in a loop won't be testing the invocation of the function, but a loop that invokes the function. |
One source of variance is that failing to give your benchmarking process priority on your system can lead to something else getting a higher priority and affecting the benchmark. But since someone's machine isn't necessarily going to assign a similar priority to their own processes, it's arguably not bad to do this. They're close enough in execution time such that users aren't likely to notice either. It's the lack of allocations in the bigger ones where this comes into play. |
Here are all results so far: BenchmarkDotNet=v0.11.5, OS=Windows 10.0.17763.557 (1809/October2018Update/Redstone5)
Intel Core i5-4690K CPU 3.50GHz (Haswell), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=3.0.100-preview5-011568
[Host] : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT DEBUG
DefaultJob : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT List.choose
List.tryPick
List.unfoldV
Array.choose
Array.tryPick
Array.unfoldV
|
Why are there still allocations for the ValueSome implementation 🤔 ? |
I've converted this into a draft (feature is available now!) I think I'm fine with the APIs getting added but @dsyme should have a say and this would need to also undergo an RFC |
@cartermp, we should try to move this forward, so we can get some preview time in for it before F# 5.0 |
Tests Fixed, and Experimental added. |
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.
These look good to me.
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.
Putting in a block since fsharp/fslang-suggestions#739 is not an approved change - @dsyme will need to have a say here
I had a brief look at why
As a consequence, even after JIT inlining and optimization, the I tested some other ways of coding Note that the normal overhead of |
@cmeeren Thanks Kevin |
I don't see what more I can do; this seems to be approved by everyone except that @dsyme needs to have a look at it (or at least approve fsharp/fslang-suggestions#739). |
See fsharp/fslang-suggestions#739
I have simply copied the existing
Option
-based implementations and tried to adapt them trivially toValueOption
. Note that I was unable to build the solution (before I started working), so I have made these edits without an IDE.I need help with adding
ValueOption
equivalents ofMicrosoft.FSharp.Primitives.Basics.List.choose
Microsoft.FSharp.Primitives.Basics.List.unfold
because I don't know where to find them. Other than that, I don't know of anything else that needs to be done here (as long as it compiles).
Note that I have absolutely no need to have my name on these changes; I have only created this PR in the hope that it might speed up the completion of fsharp/fslang-suggestions#739. I'm completely fine with this PR being thrown away in favor of another implementation.