-
-
Notifications
You must be signed in to change notification settings - Fork 833
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
Expanded Decorator Benchmarks and tests for #1113 #1116
Conversation
…ior around resolving IEnumerable<T> and T when decorators are in play -- Exposes issue #1113 in a number of skipped tests
…ecorators -- Altered base decorator benchmarks to perform multiple iterations to meansure repeats
public virtual void EnumerableResolve() | ||
[Arguments(1)] | ||
[Arguments(2)] | ||
[Arguments(3)] |
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 expanded on all of the decorator benchmarks to have repetition runs, since the first execution of Resolve<> is always really fast, but seeing the effect of repeated resolutions when using shared or independent resolutions provided some good data. My BenchmarkDotNet experience is literally only these files, so if there are recommendations for improvement, I'm all ears!
Sample output with repetitions for KeylessNestedSharedInstanceLambdaBenchmark:
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.
Just so you are aware, BenchmarkDotNet outputs a markdown file that contains GitHub-compatible markdown you can just paste straight here (rather than needing an image).
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.
The problem with the repetition approach you have here is that the benchmark methods are already being executed millions of times as it is, against a single Container
instance, to get the average time. See the comment on the repetition logic as to why you are actually seeing a discrepancy between 1 and 2.
So, 99.999999% of runs are going to be using the shared instance.
This sort of global state behaviour with benchmarks is always fun. In this particular case, my suggestion to you would be to resolve from a lifetime scope, and use a baseline to determine the cost of creating the lifetime scope.
Something like:
- Change the shared scope of the benchmarks to be lifetime scope, rather than SingleInstance.
- Derive from a new base class
ScopedDecoratorBenchmarkBase
(or something). - In this benchmark class, create a new lifetime scope at the beginning of each benchmark, and resolve from that.
- Add a new baseline benchmark in your new base class that's only job is to create and dispose of a lifetime scope. This gives us the 'no-op' cost of the actual benchmarks.
Hope that was clear, I really like benchmarks, but they can be a bit black-magic sometimes.
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.
The suggestion is completely clear! I misunderstood how global "GlobalSetup" really was, so I see how that + repetition didn't quite do what I was thinking it was doing. I was coming at it from the perspective of the fact that a single call to Resolve<>() doesn't really expose the costs of just the instance lookup when the initial resolve created a shared instance. With your suggestion about creating a lifetime scope, I'm assuming the repetition element would still be valuable, since it would expose the costs of instance lookup vs instance creation?
The benchmark stuff is definitely really interesting, though. I'll be spending some time over the next couple of months to see how I might be able to leverage BenchmarkDotNet or something similar at work
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.
Correct, the repetition would still be valuable in that case, because you'd be resolving X times from the lifetime scope before it is disposed.
I'd expect to see the highest cost on the first resolve, then lower on the second, and all subsequent repetitions should be of similar cost to the second.
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.
Because the new benchmarks introduce shared state into the container, we'll have to make some changes; benchmarks are fun!
public virtual void EnumerableResolve() | ||
[Arguments(1)] | ||
[Arguments(2)] | ||
[Arguments(3)] |
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.
Just so you are aware, BenchmarkDotNet outputs a markdown file that contains GitHub-compatible markdown you can just paste straight here (rather than needing an image).
public virtual void EnumerableResolve() | ||
[Arguments(1)] | ||
[Arguments(2)] | ||
[Arguments(3)] |
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.
The problem with the repetition approach you have here is that the benchmark methods are already being executed millions of times as it is, against a single Container
instance, to get the average time. See the comment on the repetition logic as to why you are actually seeing a discrepancy between 1 and 2.
So, 99.999999% of runs are going to be using the shared instance.
This sort of global state behaviour with benchmarks is always fun. In this particular case, my suggestion to you would be to resolve from a lifetime scope, and use a baseline to determine the cost of creating the lifetime scope.
Something like:
- Change the shared scope of the benchmarks to be lifetime scope, rather than SingleInstance.
- Derive from a new base class
ScopedDecoratorBenchmarkBase
(or something). - In this benchmark class, create a new lifetime scope at the beginning of each benchmark, and resolve from that.
- Add a new baseline benchmark in your new base class that's only job is to create and dispose of a lifetime scope. This gives us the 'no-op' cost of the actual benchmarks.
Hope that was clear, I really like benchmarks, but they can be a bit black-magic sometimes.
…re each benchmark iteration actually creates instances on the first Resolve<> for the decorators
@@ -8,18 +8,30 @@ public abstract class DecoratorBenchmarkBase<TCommandHandler> | |||
{ | |||
protected IContainer Container { get; set; } | |||
|
|||
[Benchmark(Baseline =true)] | |||
public virtual void Baseline() |
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 updated the base for all of the decorators to carry the same lifetime scope baseline and work, just so everything was an apples-to-apples comparison.
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.
Looks good!
@VonOgre, just to be thorough (and for posterity), could you please run all the benchmarks from I'd do the develop ones myself, but then before and after wouldn't be running on the same hardware. |
@alistairjevans - You got it! Long comment incoming ;) Just kidding, I found collapsible section markdown syntax! Interestingly, comparing the shared instance and instance per dependency timings for the decorators seem to indicate that the lion's share of the cost is in the lookup, rather than instantiation. It might be in part due to how simple the resolution is in these too Original BenchmarksExpand
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
New BenchmarksExpand
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.201
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.201
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i9-9900K CPU 3.60GHz (Coffee Lake), 1 CPU, 16 logical and 8 physical cores
.NET Core SDK=3.1.200
[Host] : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
DefaultJob : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT
|
Cool, I didn't actually know about the collapsible markdown, that's a neat trick. Thanks for the efforts on getting the extra benchmarks sorted; we're in a good place to assess any of the decorator lifetime changes now! 🎉 |
A response to good feedback from PR #1114 that I subsequently abandoned to start on a clean slate.
This adds skipped unit tests that illustrate issue #1113 and adds/expands on the decorator benchmarks.