-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Benchmarks for Alternative Implementations, Inline, and InlineIfLambda (
#166) * benchmarks * update gitignore * Remove artifacts * Adds InlineIfLambda variants * Adds additional variations on benchmark * revert Result.fs * Adds bind CE and bind same benchmarks * Adding Task and Async Result CE benchmarks * First pass at InlineIfLambda with backwards compatability * formatting async.fc * Convert AsyncOption.fs to use InlineIfLambda * get tests running for each netstandard * Gets all tests working with correct TFM split * Update FAKE to fix CI * formatting * update dotnet-fable * AsyncOptionCE using inlineiflambda * Update CI to install dotnet versions * global json woes? * formatting * AsyncResult InlineIfLambda * AsyncResultCE and Op InlineIfLambda * AsyncResultOption InlineIfLambda * Option InlineIfLambda * formatting * Result InlineIfLambda * Validation InlineIfLambda * ValueOption inlineiflambda * AsyncSeq InlineIfLambda * Speedily added InlineIfLambda to Taskresult * speedily add InlineIfLambda to JobResult * warning cleanups * That fun CI wackahole part 1 * That fun CI wackahole * That fun CI wackahole * Move fake build to console app * Paket targets * no more need for double underscore in classes
- Loading branch information
1 parent
f5019f1
commit 69b0019
Showing
86 changed files
with
4,336 additions
and
1,184 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
namespace FsToolkit.ErrorHandling.Benchmarks | ||
|
||
open System | ||
open BenchmarkDotNet | ||
open BenchmarkDotNet.Attributes | ||
open FsToolkit.ErrorHandling | ||
module AsyncResultCE = | ||
|
||
|
||
type AsyncResultInlinedLambdaBuilder() = | ||
|
||
member _.Return(value: 'T) : Async<Result<'T, 'TError>> = async.Return <| result.Return value | ||
|
||
member inline _.ReturnFrom(asyncResult: Async<Result<'T, 'TError>>) : Async<Result<'T, 'TError>> = asyncResult | ||
|
||
member _.Zero() : Async<Result<unit, 'TError>> = async.Return <| result.Zero() | ||
|
||
member inline _.Bind | ||
( | ||
asyncResult: Async<Result<'T, 'TError>>, | ||
[<InlineIfLambda>] binder: 'T -> Async<Result<'U, 'TError>> | ||
) : Async<Result<'U, 'TError>> = | ||
async.Bind(asyncResult, fun r -> | ||
match r with | ||
| Ok x -> binder x | ||
| Error e -> Error e |> async.Return | ||
) | ||
member inline _.Delay([<InlineIfLambda>] generator: unit -> Async<Result<'T, 'TError>>) : Async<Result<'T, 'TError>> = | ||
async.Delay generator | ||
|
||
/// <summary> | ||
/// Method lets us transform data types into our internal representation. This is the identity method to recognize the self type. | ||
/// | ||
/// See https://stackoverflow.com/questions/35286541/why-would-you-use-builder-source-in-a-custom-computation-expression-builder | ||
/// </summary> | ||
member inline _.Source(result: Async<Result<_, _>>) : Async<Result<_, _>> = result | ||
open AsyncResultCE | ||
|
||
|
||
|
||
|
||
[<AutoOpen>] | ||
// Having members as extensions gives them lower priority in | ||
// overload resolution and allows skipping more type annotations. | ||
module AsyncResultCEExtensions = | ||
|
||
type AsyncResultInlinedLambdaBuilder with | ||
/// <summary> | ||
/// Needed to allow `for..in` and `for..do` functionality | ||
/// </summary> | ||
member inline _.Source(s: #seq<_>) = s | ||
|
||
/// <summary> | ||
/// Method lets us transform data types into our internal representation. | ||
/// </summary> | ||
member inline _.Source(result: Result<_, _>) : Async<Result<_, _>> = Async.singleton result | ||
let rec fib n = | ||
if n < 2L then n | ||
else fib (n - 1L) + fib (n - 2L) | ||
|
||
let rec afib (n, level) = async { | ||
if n < 0L then return Error "No" | ||
elif n < 2L then | ||
return Ok n | ||
elif n < level then | ||
return Ok (fib n) | ||
else | ||
let! n2a = afib (n-2L, level) |> Async.StartChild | ||
let! n1 = afib (n-1L, level) | ||
let! n2 = n2a | ||
match n1, n2 with | ||
| Ok n1, Ok n2 -> | ||
return Ok (n2 + n1) | ||
| Error e, _ | ||
| _, Error e -> return Error e | ||
} | ||
let asyncResultInlinedIfLambda = AsyncResultInlinedLambdaBuilder() | ||
|
||
[<MemoryDiagnoser>] | ||
type AsyncResult_BindCEBenchmarks () = | ||
|
||
[<Benchmark(Baseline = true)>] | ||
member this.afib() = | ||
afib(10,5) | ||
|> Async.StartAsTask | ||
|
||
[<Benchmark>] | ||
member this.Result_Normal_Bind_CE() = | ||
let action () = asyncResult { | ||
let! a = Ok 10 | ||
let! b = Ok 5 | ||
let! c = afib(a, b) | ||
return c | ||
} | ||
action () | ||
|> Async.StartAsTask | ||
|
||
|
||
[<Benchmark>] | ||
member this.Result_Alt_Inlined_Bind_CE () = | ||
let action () = asyncResultInlinedIfLambda { | ||
let! a = Ok 10 | ||
let! b = Ok 5 | ||
let! c = afib(a, b) | ||
return c | ||
} | ||
action () | ||
|> Async.StartAsTask |
Oops, something went wrong.