Skip to content

Commit

Permalink
Round off stack trace work and increase yielding loop perf
Browse files Browse the repository at this point in the history
  • Loading branch information
NinoFloris committed Aug 13, 2020
1 parent 5c556e8 commit 9cf35fd
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 359 deletions.
34 changes: 17 additions & 17 deletions Benchmarks/Benchmarks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -37,37 +37,37 @@ type MicroBenchmark() =
ret() |> ignore

[<MemoryDiagnoser>]
[<SimpleJob(targetCount = 20)>]
[<SimpleJob(targetCount = 15)>]
type TaskBuildersBenchmark() =
let oldTask = ContextSensitive.task

let arbitraryWork(work) = CS.Benchmarks.ArbitraryWork(work)

// Keep at 100 minimum otherwise the C# version will do an await while the F# version
// 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 = 100
let loopCount = 5
let workFactor = 200
let loopCount = 100000

[<Benchmark(Description = "Ply")>]
member _.TaskBuilderOpt () =
(task {
do! Task.Yield()
let! arb = Task.Run(arbitraryWork workFactor)
let! v = vtask {
let! v = task {
return! ValueTask<_>(arb)
}

let mutable i = loopCount
while i > 0 do
let! y = Task.Run(arbitraryWork workFactor).ConfigureAwait(false)
i <- i - 1
return ()

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 () =
member _.TaskBuilder () =
(oldTask {
do! Task.Yield()
let! arb = Task.Run(arbitraryWork workFactor)
Expand All @@ -76,14 +76,14 @@ type TaskBuildersBenchmark() =
}

let mutable i = loopCount
while i > 0 do
let! y = Task.Run(arbitraryWork workFactor).ConfigureAwait(false)
i <- i - 1
return ()

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
CS.Benchmarks.CsTasks(workFactor, loopCount).Result
4 changes: 2 additions & 2 deletions Benchmarks/Benchmarks.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand All @@ -21,4 +21,4 @@
<PackageReference Include="TaskBuilder.fs" Version="2.1.0" />
</ItemGroup>

</Project>
</Project>
10 changes: 5 additions & 5 deletions Benchmarks/CS/Benchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ public static async ValueTask<int> CsTasks(int workFactor, int loopCount)
{
await Task.Yield();
var arb = await Task.Run(ArbitraryWork(workFactor));
async Task<int> Func() => await new ValueTask<int>(arb);
var v = await Func();

var i = loopCount;
while (i > 0)
{
var a = await Task.Run(ArbitraryWork(workFactor)).ConfigureAwait(false);
if (i % 2 == 0)
await Task.Run(ArbitraryWork(workFactor)).ConfigureAwait(false);
i = i - 1;
}

Func<ValueTask<int>> x = async () => await new ValueTask<int>(arb);
var v = await x();

if (v > 0)
{
return await new ValueTask<int>(v);
Expand All @@ -38,4 +38,4 @@ public static async ValueTask<int> CsTasks(int workFactor, int loopCount)
}
}
}
}
}
2 changes: 1 addition & 1 deletion Benchmarks/CS/CS.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>
7 changes: 3 additions & 4 deletions ComputationBuilders.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Copyright (c) 2019 Crowded B.V.
// Distributed under the MIT License (https://opensource.org/licenses/MIT).

#nowarn "44"
namespace FSharp.Control.Tasks

open Ply
Expand Down Expand Up @@ -40,7 +39,7 @@ module Builders =

let unitVtask = UnitValueTaskBuilder()

module Unsafe =
module Unsafe =
type UnsafePlyBuilder() =
inherit AwaitableBuilder()
member inline __.Run(f : unit -> Ply<'u>) = runUnwrappedAsPly f
Expand All @@ -60,10 +59,10 @@ module Builders =
member inline __.Run(f : unit -> Ply<'u>) = runUnwrapped f

let uvtask = UnsafeValueTaskBuilder()

type UnsafeUnitValueTaskBuilder() =
inherit AwaitableBuilder()
member inline __.Run(f : unit -> Ply<'u>) =
member inline __.Run(f : unit -> Ply<'u>) =
let t = runUnwrapped f
if t.IsCompletedSuccessfully then ValueTask() else ValueTask(t.AsTask() :> Task)

Expand Down
Loading

0 comments on commit 9cf35fd

Please sign in to comment.