-
Notifications
You must be signed in to change notification settings - Fork 17
/
Benchmarks.fs
89 lines (78 loc) · 2.84 KB
/
Benchmarks.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
namespace Benchmarks
open BenchmarkDotNet.Attributes
open System.Threading.Tasks
open FSharp.Control.Tasks.V2 // TaskBuilder.fs
open FSharp.Control.Tasks // Ply
open FSharp.Control.Tasks.Affine.Unsafe // Ply
[<MemoryDiagnoser>]
[<SimpleJob(targetCount = 10)>]
type MicroBenchmark() =
[<Benchmark(OperationsPerInvoke = 100000)>]
member _.AllocFreeReturn() =
for _ = 0 to 100000 do
let ret () =
uply {
return! uvtask {
return! uply {
return 1
}
}
}
ret() |> ignore
[<Benchmark(OperationsPerInvoke = 1000)>]
member _.SyncExceptionSuspend() =
for _ = 0 to 1000 do
let ret () =
uply {
return! uvtask {
return! uply {
invalidOp "Will be suspended in an awaitable"
return ()
}
}
}
ret() |> ignore
[<MemoryDiagnoser>]
[<SimpleJob(targetCount = 15)>]
type TaskBuildersBenchmark() =
let oldTask = ContextSensitive.task
let arbitraryWork(work) = CS.Benchmarks.ArbitraryWork(work)
// Keep at 200 minimum otherwise the C# version will do an await while the F# version
// gets IsCompleted true due to a few more calls in between running and checking
let workFactor = 200
let loopCount = 100000
[<Benchmark(Description = "Ply")>]
member _.TaskBuilderOpt () =
(task {
do! Task.Yield()
let! arb = Task.Run(arbitraryWork workFactor)
let! v = task {
return! ValueTask<_>(arb)
}
let mutable i = loopCount
while i > 0 do
if i % 2 = 0 then
let! y = Task.Run(arbitraryWork workFactor).ConfigureAwait(false)
()
i <- i - 1
if v > 0 then return! ValueTask<_>(v) else return 0
}).Result
[<Benchmark(Description = "TaskBuilder.fs v2.1.0")>]
member _.TaskBuilder () =
(oldTask {
do! Task.Yield()
let! arb = Task.Run(arbitraryWork workFactor)
let! v = oldTask {
return! ValueTask<_>(arb)
}
let mutable i = loopCount
while i > 0 do
if i % 2 = 0 then
let! y = Task.Run(arbitraryWork workFactor).ConfigureAwait(false)
()
i <- i - 1
if v > 0 then return! ValueTask<_>(v) else return 0
}).Result
[<Benchmark(Description = "C# Async Await", Baseline = true)>]
member _.CSAsyncAwait () =
CS.Benchmarks.CsTasks(workFactor, loopCount).Result