Skip to content

Commit

Permalink
203 - Removing lock in Scope to improve performance (#322)
Browse files Browse the repository at this point in the history
* removing locks

* replacing Thread.Sleep with Monitor.Wait / PulseAll

* updating benchmark results

* storing the current bm results to compare later

* fixing the wrong the lock

* factoring out the waiting code and the LoadBenchmarks and the BMs with prev Autofac

* index on issue_203: 5c2a11d factoring out the waiting code and the LoadBenchmarks and the BMs with prev Autofac

* fixes and refactorings; tests are passing; added new RegisterInitializer with reuse

* fixing the build

Co-authored-by: maximv <maximv@cynet.com>
  • Loading branch information
dadhi and maximv authored Oct 11, 2020
1 parent 85ea415 commit de9f0a7
Show file tree
Hide file tree
Showing 9 changed files with 630 additions and 342 deletions.
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

0 comments on commit de9f0a7

Please sign in to comment.