Last active
June 9, 2022 19:28
-
-
Save mrange/a7372cdf05356fa24cff6b25da7cb1e0 to your computer and use it in GitHub Desktop.
Testing Fusion vs Fission in F#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>net6.0</TargetFramework> | |
</PropertyGroup> | |
<ItemGroup> | |
<Compile Include="Program.fs" /> | |
</ItemGroup> | |
<ItemGroup> | |
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" /> | |
</ItemGroup> | |
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
// * Summary * | |
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1741 (21H2) | |
Intel Core i5-3570K CPU 3.40GHz (Ivy Bridge), 1 CPU, 4 logical and 4 physical cores | |
.NET SDK=6.0.300 | |
[Host] : .NET 6.0.5 (6.0.522.21309), X64 RyuJIT DEBUG | |
DefaultJob : .NET 6.0.5 (6.0.522.21309), X64 RyuJIT | |
| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Allocated | | |
|-------------- |---------:|---------:|---------:|------:|--------:|---------:|----------:| | |
| Baseline | 15.43 us | 0.037 us | 0.035 us | 1.00 | 0.00 | - | - | | |
| BuiltIn | 15.40 us | 0.026 us | 0.025 us | 1.00 | 0.00 | - | - | | |
| Fusion | 68.65 us | 1.223 us | 1.085 us | 4.45 | 0.07 | 101.9287 | 320,032 B | | |
| Fusion_Struct | 95.14 us | 0.281 us | 0.263 us | 6.17 | 0.02 | - | - | | |
| Fission | 30.93 us | 0.059 us | 0.055 us | 2.00 | 0.01 | - | - | | |
*) | |
open BenchmarkDotNet | |
open BenchmarkDotNet.Attributes | |
open BenchmarkDotNet.Running | |
[<MemoryDiagnoser>] | |
type Benchmarks () = | |
class | |
let vs = List.init 10000 float | |
[<Benchmark(Baseline = true)>] | |
member x.Baseline () = | |
// Baseline is the basic for loop in F# | |
// assuming the foreach is implemented | |
// efficiently in F# this should give | |
// one of the better results | |
let mutable sum = 0.0 | |
let mutable cnt = 0 | |
for v in vs do | |
sum <- sum + v | |
cnt <- cnt + 1 | |
sum / float cnt | |
[<Benchmark>] | |
member x.BuiltIn () = | |
// List.average is likely quick as well | |
vs |> List.average | |
[<Benchmark>] | |
member x.Fusion () = | |
// Using Fusion with reference tuples | |
// We expect this to incur some GC tax | |
let sumLength (sumAcc, cntAcc) (x : float) = (sumAcc + x, cntAcc + 1) | |
let sum, cnt = List.fold sumLength (0.0, 0) vs | |
sum / float cnt | |
[<Benchmark>] | |
member x.Fusion_Struct () = | |
// Using Fusion with struct tuples | |
// No GC tax expected but struct values have their own overhead | |
let sumLength (struct (sumAcc, cntAcc)) (x : float) = struct (sumAcc + x, cntAcc + 1) | |
let struct (sum, cnt) = List.fold sumLength (struct (0.0, 0)) vs | |
sum / float cnt | |
[<Benchmark>] | |
member x.Fission () = | |
// Using Fission | |
let sum = vs |> List.sum | |
let cnt = vs |> List.length | |
sum / float cnt | |
end | |
let _ = BenchmarkRunner.Run<Benchmarks>() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment