Skip to content
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

203 - Removing lock in Scope to improve performance #322

Merged
merged 10 commits into from
Oct 11, 2020
118 changes: 105 additions & 13 deletions playground/LoadTest/LoadTestBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,14 @@ public class LoadTestBenchmark
{
/*
# v4.1.5 - Singleton decorators
-------------------------------

Validation finished
00:01:24.33

ResolveAllControllersOnce of 156 controllers is done in 0.1533677 seconds

----------------------------------
Starting compiled + cached tests
----------------------------------

New container created

container with ambient ScopeContext DryIoc.AsyncExecutionFlowScopeContext without scope
with Rules with Made={FactoryMethod=ConstructorWithResolvableArguments}

ResolveAllControllersOnce of 156 controllers is done in 0.0073486 seconds
ResolveAllControllersOnce of 156 controllers is done in 0.1591292 seconds

# v4.2.0 - Singleton decorators
-------------------------------

New container created:

Expand All @@ -57,6 +46,109 @@ ResolveAllControllersOnce of 156 controllers is done in 0.1624977 seconds
ResolveAllControllersOnce of 156 controllers is done in 13.0481077 seconds
## Invoking the cached delegate...
ResolveAllControllersOnce of 156 controllers is done in 0.0262042 seconds

# v4.4.1 - Singleton decorators
-------------------------------

# LoadTestBenchmark
New container created:

container with ambient DryIoc.AsyncExecutionFlowScopeContext without scope
with Rules with Made={FactoryMethod=ConstructorWithResolvableArguments}

Validating controllers only...

Validation finished
00:00:00.08

ResolveAllControllersOnce of 156 controllers is done in 0.4730469 seconds

----------------------------------
Starting compiled + cached tests
----------------------------------

New container created:

container with ambient DryIoc.AsyncExecutionFlowScopeContext without scope
with Rules with Made={FactoryMethod=ConstructorWithResolvableArguments}

## Interpreting...
ResolveAllControllersOnce of 156 controllers is done in 0.1592902 seconds
## Compiling and caching the delegate...
ResolveAllControllersOnce of 156 controllers is done in 13.0788307 seconds
## Invoking the cached delegate...
ResolveAllControllersOnce of 156 controllers is done in 0.0379507 seconds
-- Starting Load test --
32 Threads.

-- Load Test Finished --
00:00:17.97

-- 1st Randomized Load Finished --
00:02:06.97

-- 2nd Randomized Load Finished --
00:02:39.36

---------------------------------------
Starting cold run tests
This can take a long time...
---------------------------------------

New container created:

container with ambient DryIoc.AsyncExecutionFlowScopeContext without scope
with Rules with Made={FactoryMethod=ConstructorWithResolvableArguments}

-- Starting Load test --
32 Threads.

-- Load Test Finished --
00:00:43.66


# v4.5

Validation finished
00:00:00.10

ResolveAllControllersOnce of 156 controllers is done in 0.4809402 seconds

New container created: container with ambient DryIoc.AsyncExecutionFlowScopeContext without scope
with Rules with Made={FactoryMethod=ConstructorWithResolvableArguments}

## Interpreting...
ResolveAllControllersOnce of 156 controllers is done in 0.2221077 seconds
## Compiling and caching the delegate...
ResolveAllControllersOnce of 156 controllers is done in 19.1688573 seconds
## Invoking the cached delegate...
ResolveAllControllersOnce of 156 controllers is done in 0.0337507 seconds
-- Starting Load test --
32 Threads.

-- Load Test Finished --
00:00:22.54

New container created:

container with ambient DryIoc.AsyncExecutionFlowScopeContext without scope
with Rules with Made={FactoryMethod=ConstructorWithResolvableArguments}

## Interpreting...
ResolveAllControllersOnce of 156 controllers is done in 0.2457103 seconds
## Compiling and caching the delegate...
ResolveAllControllersOnce of 156 controllers is done in 20.6428925 seconds
## Invoking the cached delegate...
ResolveAllControllersOnce of 156 controllers is done in 0.0441964 seconds
-- Starting Randomized Load test --
155 Threads.

-- Randomized Load Finished --
00:02:51.94

-- Load Test Finished --
00:00:52.47

*/

public static IContainer RootContainer = null;
Expand Down
2 changes: 1 addition & 1 deletion playground/Playground/Playground.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework Condition="'$(NoSupportForNetCore22)' == 'true'">netcoreapp2.1</TargetFramework>
<!-- <TargetFramework Condition="'$(DevMode)' == 'true'">netcoreapp3.1</TargetFramework> -->
<!--TargetFramework>netcoreapp3.1</TargetFramework-->

<Description>Benchmarks, sandbox for experiments.</Description>

Expand Down
37 changes: 26 additions & 11 deletions playground/Playground/RealisticUnitOfWorkBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,21 @@ public class CreateContainerAndRegisterServices_Then_FirstTimeOpenScopeAndResolv
| MsDI | 113.8 us | 2.26 us | 6.06 us | 1.00 | 0.00 | 18.0664 | 0.1221 | - | 73.85 KB |
| DryIoc | 107.6 us | 1.83 us | 1.71 us | 1.00 | 0.13 | 16.4795 | 0.1221 | - | 67.52 KB |
| DryIoc_MsDI | 129.8 us | 1.03 us | 0.91 us | 1.22 | 0.18 | 21.4844 | 0.2441 | - | 88.6 KB |

## DryIoc 4.4.1

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041
Intel Core i7-8565U CPU 1.80GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.402
[Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT
DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT

| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------ |---------:|--------:|--------:|------:|--------:|--------:|-------:|------:|----------:|
| MsDI | 132.4 us | 1.78 us | 1.66 us | 1.00 | 0.00 | 18.0664 | 0.2441 | - | 73.86 KB |
| DryIoc | 112.1 us | 1.33 us | 1.24 us | 0.85 | 0.01 | 16.4795 | 0.1221 | - | 67.52 KB |
| DryIoc_MsDI | 141.0 us | 1.54 us | 1.36 us | 1.07 | 0.02 | 21.4844 | 0.2441 | - | 88.6 KB |

*/
[Benchmark(Baseline = true)]
public object MsDI() => Measure(PrepareMsDi());
Expand Down Expand Up @@ -1367,16 +1382,16 @@ public class OpenScopeAndResolve
| DryIoc | 1.868 us | 0.0226 us | 0.0200 us | 0.44 | 0.01 | 0.7248 | - | - | 2.96 KB |
| DryIoc_MsDIAdapter | 2.651 us | 0.0404 us | 0.0338 us | 0.63 | 0.02 | 0.7286 | - | - | 2.98 KB |

#### No locking in Scope - commenting the `lock` in `Scope.TryGetOrAddViaFactoryDelegate`
### DryIoc v4.5.0 - no scope locking, Autofac 6, Grace 7.1.1

| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------- |---------:|----------:|----------:|------:|-------:|------:|------:|----------:|
| MsDI | 4.310 us | 0.0854 us | 0.0877 us | 1.00 | 1.0605 | - | - | 4.35 KB |
| DryIoc | 1.613 us | 0.0144 us | 0.0135 us | 0.37 | 0.7229 | - | - | 2.96 KB |
| DryIoc_MsDIAdapter | 2.373 us | 0.0322 us | 0.0269 us | 0.55 | 0.7286 | - | - | 2.98 KB |
| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
|-------- |----------:|----------:|----------:|------:|--------:|--------:|-------:|------:|----------:|
| MsDI | 6.233 us | 0.1235 us | 0.1994 us | 1.00 | 0.00 | 1.0605 | - | - | 4.35 KB |
| DryIoc | 2.377 us | 0.0475 us | 0.0915 us | 0.38 | 0.02 | 0.7248 | - | - | 2.96 KB |
| Grace | 2.997 us | 0.0592 us | 0.1274 us | 0.48 | 0.02 | 0.7744 | - | - | 3.17 KB |
| Autofac | 86.368 us | 1.7046 us | 3.4820 us | 13.88 | 0.82 | 11.4746 | 0.1221 | - | 47.34 KB |

*/

private IServiceProvider _msDi;
private IContainer _dryIoc;
private IContainer _dryIocWithoutFEC;
Expand Down Expand Up @@ -1419,7 +1434,7 @@ public void WarmUp()
[Benchmark]
public object DryIoc() => Measure(_dryIoc);

[Benchmark]
// [Benchmark]
public object DryIoc_MsDIAdapter() => Measure(_dryIocMsDi);

//[Benchmark]
Expand All @@ -1428,7 +1443,7 @@ public void WarmUp()
//[Benchmark]
public object DryIoc_InterpretationOnly() => Measure(_dryIocInterpretationOnly);

//[Benchmark]
[Benchmark]
public object Grace() => Measure(_grace);

//[Benchmark]
Expand All @@ -1437,10 +1452,10 @@ public void WarmUp()
//[Benchmark]
public object Lamar_MsDI() => Measure(_lamarMsDi);

//[Benchmark]
[Benchmark]
public object Autofac() => Measure(_autofac);

//[Benchmark]
// [Benchmark]
public object Autofac_MsDIAdapter() => Measure(_autofacMsDi);
}
}
Expand Down
Loading