-
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
Optimize DateTime comparison/equality #9224
Conversation
This is a small benchmark program I used to compare the two: open System
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Running
[<MemoryDiagnoser>]
type DateTimeBench() =
let maxTime = DateTime.MaxValue
let data =
[
for x in 0..100 ->
DateTime (int64 x)
]
[<Benchmark(Baseline=true)>]
member _.UsingMax() =
let rec f xs acc =
match xs with
| [] -> acc
| h::t -> f t (max acc h)
f data maxTime
[<Benchmark>]
member _.UsingDateTimeCompare() =
let rec f xs acc =
match xs with
| [] -> acc
| h::t ->
let res = DateTime.Compare(acc, h)
if res >= 0 then
f t acc
else
f t h
f data maxTime
[<EntryPoint>]
let main argv =
let summary = BenchmarkRunner.Run<DateTimeBench>()
printfn "%A" summary
0 // return an integer exit code It yielded these results: BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.836 (1909/November2018Update/19H2)
Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.100-preview.4.20258.7
[Host] : .NET Core 5.0.0 (CoreCLR 5.0.20.25106, CoreFX 5.0.20.25106), X64 RyuJIT DEBUG
DefaultJob : .NET Core 5.0.0 (CoreCLR 5.0.20.25106, CoreFX 5.0.20.25106), X64 RyuJIT
|
wow - rewrite rule for Optimizer? ;-) |
I think the more appropriate general purpose fix is to get these generic functions to stop allocating on structs that aren't specialized in FSharp.Core |
@cartermp did you run the perftest with max using this fix? |
The test failures are from baseline comparisons against the emitted IL in the fsharpqa suite. How does babby update? |
@cartermp you should be able to use https://github.com/dotnet/fsharp/blob/master/TESTGUIDE.md#baselines after seeing the tests fail locally. |
Updated failing baselines |
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 think the test changes are good, but I think we don't need to update FSharp.Core. We simply need to do devirtualization on equality and comparison and just emit the equals. Here was the PR when devirting equality, #6175. We could expand it to comparison.
This sort of thing needs to be expanded to all struct types...
Seems I was a little too late as this was merged 2 minutes before submitting my review. |
Now I'm confused - @TIHan @KevinRansom what we discussed was that we would place these in FSharp.Core, which is why I made this adjustment rather than keeping them in the compiler. This was because it's an easy improvement with no apparent problems, whereas #6175 and extensions to it would be too tricky and time-consuming to land right now. Or am I mistaken in my recollection of that discussion? |
@cartermp , your recollection matches mine. I think we need a backlog item to make the change that will is thinking about. However, that requires time to design, bake and think through. |
* Replace 'max' with DateTime.Compare in ComputeMaxTimeStamp * Generalize datetime in fsharp.core * baselines Co-authored-by: Kevin Ransom <codecutter@hotmail.com>
In a trace from here: https://developercommunity.visualstudio.com/content/problem/1035124/trace-of-editing-experience-with-in-memory-cross-p-1.html
I found that
ComputeMaxTimeStamp
was allocating a lot ofDateTime
s, stemming from the call tomax
:This replaced it with a call toDateTime.Compare
, which won't allocate.After talking with @TIHan and @KevinRansom, this added some DateTime specializations to FSharp.Core so that equality, comparison, min, max, etc. all specialize to the right method rather than box the DateTime structs.