Code Monkey home page Code Monkey logo

iocperformance's Introduction

Ioc Performance

Build Status

Source code of my performance comparison of the most popular .NET IoC containers:
www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison

Author: Daniel Palme
Blog: www.palmmedia.de
Twitter: @danielpalme

Results

Explantions

First value: Time of single-threaded execution in [ms]
Second value: Time of multi-threaded execution in [ms]
*: Benchmark was stopped after 1 minute and result is extrapolated.

Basic Features

Container Singleton Transient Combined Complex
No 41
49
49
59
69
76
99
103
abioc 0.8.0 26
43
33
56
51
82
67
78
Autofac 7.0.1 1010
590
969
659
3118
1917
8470
5543
Caliburn.Micro 1.5.2 465
270
533
322
1583
906
7403
3712
Catel 5.12.22 250
296
3979
4314
8954
9876
25104
23025
DryIoc 4.8.5 63
54
73
73
89
100
110
101
DryIocZero 4.0.0 110
96
88
89
98
105
220
169
Dynamo 3.0.2 95
70
104
86
207
158
685
381
Faster.Ioc 1.0.0 25
46
72
62
67
82
139
93
Grace 7.2.1 20
31
39
55
52
84
73
83
Lamar 8.0.1 61
63
86
83
117
110
130
127
LightInject 6.6.4 51
52
62
59
113
102
230
195
Maestro 3.6.6 386
269
342
241
580
438
1411
1097
Mef 4.0.0.0 22679
11820
37640
25052
57462
68730*
112712*
131716*
Mef2 7.0.0.0 298
235
327
176
327
248
621
410
MicroResolver 2.3.5 25
39
34
59
55
77
92
89
Microsoft Extensions DependencyInjection 7.0.0 68
58
96
79
110
106
131
112
Microsoft.VisualStudio.Composition 17.6.17 10905
12502
33562
21704
66196*
25605
60406*
55918
Mugen MVVM Toolkit 6.5.0 102
138
409
715
2052
2590
9348
11352
MvvmCross 8.0.2 205
251
1318
1402
3316
3726
8677
9516
Ninject 3.3.6 3809
4583
13588
11986
37822
28199
105486*
79549*
Pure.DI 2.0.0 29
33
40
62
61
88
105
104
Rezolver 2.1.0 121
100
137
126
194
171
328
238
SimpleInjector 5.4.1 87
67
71
91
152
129
233
179
Singularity 0.18.0 24
39
39
59
66
82
76
84
Spring.NET 3.0.2 565
451
3022
1649
9816
6870
28453
21414
Stashbox 5.11.0 40
47
57
69
78
94
127
111
StructureMap 4.7.1 1121
717
1281
856
3410
2166
8312
6052
Unity 5.11.10 216
148
1443
835
3326
1995
9503
4739
Windsor 6.0.0 549
533
2065
1168
6572
5948
20046
18318
ZenIoc 1.0.1 306
198
267
188
674
440
1809
1103
Zenject 8.0.0 479
448
1370
1070
3689
3065
11142
10106

Advanced Features

Container Property Generics IEnumerable Conditional Child Container Asp Net Core Interception With Proxy
No 186
134
70
75
193
176
53
63
644
596

469
438
abioc 0.8.0

799
506




Autofac 7.0.1 9031
5468
2319
1330
11000
6339
2085
1423
74767*
57993
44266
37346
24279
13732
Caliburn.Micro 1.5.2 9157
4733

5965
3393




Catel 5.12.22
8872
9710




3937
4257
DryIoc 4.8.5 144
131
86
88
294
219
81
79

1379
1005
835
555
DryIocZero 4.0.0 294
205
92
92
302
229
380
270



Dynamo 3.0.2 828
455






Faster.Ioc 1.0.0
95
87
388
287
107
66

797
635

Grace 7.2.1 101
112
50
80
257
210
45
70
50375
32231
657
674
827
571
Lamar 8.0.1 133
98
106
108
634
432


4753
4323

LightInject 6.6.4 259
142
53
69
309
280
494
273

2098
1711
1921
1005
Maestro 3.6.6 3886
2438
419
318
1272
843


10764
8560
6757
3630
Mef 4.0.0.0 124500*
133833*
137086*
114221*
97231*
100896*




Mef2 7.0.0.0 1337
921
273
195
1851
813




MicroResolver 2.3.5 39
62

262
195




Microsoft Extensions DependencyInjection 7.0.0
117
94
363
242


4263
2412

Microsoft.VisualStudio.Composition 17.6.17 47046
34542

45837
38733




Mugen MVVM Toolkit 6.5.0 436
705

9749
7094

4370
3103


MvvmCross 8.0.2 1310
1415
6576
7299


4968
3230


Ninject 3.3.6 78292*
60394*
28241
20249
92792*
68004*
24794
18311
78784000*
45766768*

22231
19065
Pure.DI 2.0.0 75
63
86
78
328
272
85
71


249
192
Rezolver 2.1.0 520
385
183
145
669
408

9589857*
5697265*
86587*
56374

SimpleInjector 5.4.1 366
204
99
103
755
738
85
83


5503
4220
Singularity 0.18.0
54
80
241
193


631
652

Spring.NET 3.0.2 21087
16280





21268
15259
Stashbox 5.11.0 148
181
108
97
542
509
74
83
871072*
663243*
2098
1280
917
643
StructureMap 4.7.1 8697
5284
2271
1460
8399
5170

3215578*
1887211*
65269*
41725
7859
4464
Unity 5.11.10 9045
5814
9842
6443
17755
12048
3547
2046
147355*
74313*
61350*
39009
56226
31096
Windsor 6.0.0 38349
32062
16588
12021
17909
14575

252113*
175868*

16722
11052
ZenIoc 1.0.1 264
195
276
209
704
488
314
222
602490*
471765*


Zenject 8.0.0 15829
13135
9021
6513
17932
12687
3082
2428
22250
18595


Prepare

Container Prepare And Register Prepare And Register And Simple Resolve
No 2
2
abioc 0.8.0 6327
6556
Autofac 7.0.1 359
367
Caliburn.Micro 1.5.2 55
56
Catel 5.12.22 11925
9956
DryIoc 4.8.5 56
64
DryIocZero 4.0.0 0
1
Dynamo 3.0.2 16240
16527
Faster.Ioc 1.0.0 51
1283
Grace 7.2.1 157
966
Lamar 8.0.1 2516
3044
LightInject 6.6.4 127
2146
Maestro 3.6.6 128
144
Mef 4.0.0.0 17
2299
Mef2 7.0.0.0 6114
6957
MicroResolver 2.3.5 27322
67518
Microsoft Extensions DependencyInjection 7.0.0 22
35
Microsoft.VisualStudio.Composition 17.6.17 9311
11123
Mugen MVVM Toolkit 6.5.0 15
19
MvvmCross 8.0.2 10
16
Ninject 3.3.6 134240*
112279*
Pure.DI 2.0.0 0

Rezolver 2.1.0 20835
27706
SimpleInjector 5.4.1 825
3214
Singularity 0.18.0 314
874
Spring.NET 3.0.2 15929
17596
Stashbox 5.11.0 202
1113
StructureMap 4.7.1 1325
7389
Unity 5.11.10 122
287
Windsor 6.0.0 3927
2927
ZenIoc 1.0.1 77
964
Zenject 8.0.0 199
201

Charts

Basic features Advanced features Prepare

Machine

The benchmark was executed on the following machine:
CPU: Intel(R) Core(TM) i5-6260U CPU @ 1.80GHz
Memory: 15,89GB

iocperformance's People

Contributors

aarnott avatar alexandrnikitin avatar alexmg avatar barsonax avatar bartizan avatar christianhenrikreich avatar dadhi avatar danielpalme avatar delpak avatar dotnetjunkie avatar eniks avatar geertvanhorrik avatar hashtagsheep avatar iamahern avatar ipjohnson avatar jonassamuelsson avatar jskimming avatar lamlex avatar lordzoltan avatar martijn00 avatar mdeangelo272 avatar minhthiendx avatar neuecc avatar pgatilov avatar reflection-emit avatar robertmccoy avatar seesharper avatar wsm2110 avatar z33bs avatar z4kn4fein avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iocperformance's Issues

Web app to display the result nicely.

I would like to contribute by creating an web app to display the test result nicely.
The results could be sorted, hidden, or graphed.
The app will be scheduled to run every times a new version of IoC is updated.
The app will be hosted on Azure App Service.

Are you interested in PR for this feature?

can't compile with vs2019

I just tried to comile with vs2019 and got the following error

Fody: PEVerify of the assembly failed.
[IL]: Error: [C:\dev\GitHub\IocPerformance\IocPerformance\bin\Debug\IocPerformance.exe : DryIocZero.Request::ToString][offset 0x0000002B] Cannot change initonly field outside its .ctor.(Error: 0x80131884)

seems to be related to your code @dadhi, can you have a look?

Level playing field

With the changes introduced with issue #71 we attempted to level the playing field and come up with a more real world test. This give a speed advantage to containers that have less features.

This wasn't a concern before as the top containers all competed in all the benchmarks (minus the child container). Now that abioc is the top container it competes in less than half the benchmarks and has a real advantage.

My suggestion is to add a method for each adapter that is called at the end of warm up to resolve some dummy services to level the play field.

So for example Stashbox, Grace and Autofac would resolve 0 dummy registration as they compete in all, LightInject, DryIoC would resolve 3 dummy registration, abioc would resolve 18 (6 benchmarks x 3) and so forth.

Root Services

The problem is that the number of root services (services resolved directly from the container) grow gradually as the various benchmarks are executed. Most containers have some kind of dictionary that maps a service type to the delegate that represents resolving the service. When we talk about the top performing containers, looking up this delegate is actually what sets them apart. Some use a simple dictionary while others use a more optimized structure such as a binary search tree.

The first test is Singleton and after warmup we will have 3 root services, ISingleton1, ISingleton2 and ISingleton3. For the next test which is Transient we will have 6 root services, ITransient1, ITransient2 and ITransient3 in addition to the 3 services from the singleton test.

This means that service lookop will gradually cost more and more as the runner loops through the tests.

When the test runner reaches the last test the container will have root services for all services retrieved through the IContainerAdapter.Resolve method. Sort of a before all warmup.

I think the best solution would be to run all the benchmarks at startup so that all root services has been resolved once before starting the main run.

This also makes for a more real-life scenario as it is not unusual to have quite a few root services in a container.

Performance regression in singularity

I have noticed a rather big sudden performance regression for Singularity in this benchmark which I cannot reproduce (by checking out this repo and running the benchmarks) and also iam not aware of any changes made to the code that might have caused this.

Just speculating here but was the benchmark accidentally run in debug mode?

Unity 5.11.1

Please update UnityContainer to the latest version

Make aspnet core benchmark more realistic

Currently the aspnet core benchmark resolves just a single scoped instances 3 times per scope. This makes it very easy to design a container that scores high on this specific workload. All one needs to do is use a datastructure thats fast on adding items and fast on returning that item if there is only 1 item. A datastructure such as a singlylinked list or even a simple field could be used for this.

Containers using such a datastructure in this case may seem to be the fastest however given the fact that such a approach does not scale very well it may give the wrong impression.

Just to give you a idea its pretty trivial to make Singularity perform 2x faster on this benchmark by doing this.

I think it would be better if:

  • More work is done per scope. Currently there is lots of overhead in creating the scope itself because the actual workload inside the scope itself is very small.
  • There are more than 1 scoped instances. This should make it harder to cheese the benchmark with a SinglyLinked list or even a simple field to store the scoped instance.
  • These scoped instances are resolved many times to put more pressure on the read performance of the particular datastructure that a given container is using. If this is not changed then the benchmark would favor datastructures that are fast on adding new items.

Compare the default asp.net core DI

There doesn't seem to be a benchmark for the asp.net core DI that comes out of the box. Would be really to find out what its figures are compared to the rest of the pack.

Resolve instances using generic "Resolve" methods

It makes results more accurate because of there are no any additional operations of conversions of type. Actually it is more sensible scenario to use these methods and all IoC containers have these methods

Discussion: How to remove "noise" from the benchmark

At the moment the benchmark contains 35 containers.

Question 1: Should containers be categorized as relevant / not relevant for the benchmark?

Question 2: Based on which criteria should containers be categorized as relevant / not relevant?

  • Only few months of history
  • Not actively maintained
  • Few features, no integration options
  • Few contributors

Question 3: What should happen with containers that are not relevant

  • Completely remove them from the benchmark
  • Create a separate list with legacy / not relevant containers

Use BenchmarkDotNet

Love this benchmark!

Change the custom benchmarking infrastructure to use BDN, it's the de-factor benchmarking tech for .NET projects now and it'll likely produce more accurate results and more detailed measurements (like allocations etc).

/cc @adamsitnik @AndreyAkinshin @mattwarren

TinyIoC Perfomance

This has been brought up in the past, but TinyIOC is one of the largest IOCS out there and should be included in any metrics.

The old issue mentioned VS2017 as the limiting factor, but since we are now on VS2019 and TinyIOC has been updated along with it I feel this warrants being brought up again.

Please add TinyIOC to the comparisons in the future. I believe a lot of people would appreciate this.
Thanks

asp.net benchmark - multiple scopes per controller

A common architecture on projects I work on is to allow multiple scopes per controller, where the controller is an entry point for parallel processing some work. For example, creating multiple DbContext objects, one per parallel unit of work. Since DbContext is not thread-safe, a Func<DbContext> is required with a way to OpenScope on the existing scope, creating a new scope that is either a child/nested scope or orthogonal scope to existing scopes.

Issues I have come across implementing this pattern include threading security context (authentication and authorization) to the parallel unit of work, as the child threads do not inherit the identity context, so the identity has to be thunked to the child threads.

`Real world` scenario specification disscussion

Real worlds scenarios involve complex object graphs. Some containers could work better or worse in such case. So current tests make me to doubtful about results as using small amount of types may lead to false results. I going to write .tt file which generates and registeres 200 classes into 3 most fastest containers and Autofac and DryIoC.

My setup will be Layered HTTP Web API like backed application.

Controller depends on Services depends on UnitOfWorks depends on Repositories. All may by even/odd or other rule depend on IEventing/ILogging/IEnvironemnt etc. All resolution is done via constructors.
Controller resolved per request. Other layers are shared for that Controller, e.g IUnitOfWork1 resolved by Service1 and Service2 is reused for Controller. IEnvironment is singleton. IAuthorization and IRouting implementations are chosen and resolved depending on current HTTP headers.

Containers resolution is done in 4 threads to imitate concurrent workload.

Results of these tests should be placed into separate spreadsheet graph.

Another options are console or desktop or mobile app.

Skewed `Advanced features`

Seems Prepare And Register and Prepare And Register And Simple Resolve broke Advanced features chart. May be create separate chart for these, this will fix issue and may allow somebody add different initialization routines (e.g. XML, assembly scan or out of previously cached container registrations).

Small problem with Warmup method

I was looking at the Warmup method in Program.cs

    private static void WarmUp(IContainerAdapter container)
    {
        var interface1 = container.Resolve<ISingleton>();
        var interface2 = container.Resolve<ITransient>();
        var combined = container.Resolve<ISingleton>();

        if (container.SupportsInterception)
        {
            var calculator = container.ResolveProxy<ICalculator>();
            calculator.Add(1, 2);
        }
    }

I believe the third line should be Resolve ICombine not Resolve ISingleton, it doesn't really make much of a difference in the results just something I noticed.

Cannot build with 4.7

Severity Code Description Project File Line Suppression State
Error CS0116 A namespace cannot directly contain members such as fields or methods IocPerformance D:\Code\IocPerformance-master\IocPerformance\Adapters\DryIocZero\Container.Generated.cs 1 Active

Building with 4.7.2.

Deleting the contents of this file allowed it to build and execute successfully. Downloaded projects should just "work" out of the box, without the need to understand build errors.

please make it clear in the description

is low better or worse, its not clear

as the graphs contradict the results then

Unity 5.11.10
 | 216 148 | 1443 835 | 3326 1995 | 9503 4739
Microsoft Extensions DependencyInjection 6.0.0 
| 65 57 | 108 82 | 108  109 | 150  115

This would indicate that the Microsoft Extensions DependencyInjection is faster yes?

but then in the graphs it shows it like how many instances were created over time

https://danielpalme.github.io/IocPerformance/

So then actually Unity is faster...

StyleMVVM Support

Hi Daniel,

I was hoping to get StyleMVVM added to the list of containers.

I've put together an Adapter that can be found on dropbox with the link below, so you should just be able to add the StyleMVVM nuget package then add the adapter.

https://www.dropbox.com/s/fj5ukhqf1v1eexg/StyleMVVMAdapter.cs

The numbers I'm getting put it as one of the faster "avergage" containers while support advanced features like Lifecycle containers, conditional exports (similar features as ninject conditional binding), Open Generic exports and more.

thanks
-Ian

Multithreaded performance is not being measured accurately

Noticed that the current benchmark does not measure the multithreaded performance accurately enough, especially when containers like singularity can do their work in less than 10 nanoseconds. I believe this is because there's too much overhead in the way the benchmark is done currently. Increasing the sample size might lead to more accurate results.

When you do this you will see that for alot of containers the multithreaded results will be faster like they should be.

Incorrect Unity testing

It seems you configure Unity with Interceptors for all of you tests. Interception introduces reflection into building strategy and is rather slow. It skews results dramatically.
I would suggest either creating two adapters with and without interception or configuring Interception only if it is required by the tests.

Most of the containers do not have interception so it creates unfair advantage when compared to the Unity. To give objective performance comparison the playing field should be leveled.

As you can see in these tests your results are way off.

Interception unfairly skewing benchmarks

I would like to suggest a small improvement to your benchmarks. It has to do with how your setup threats interception.

Generally interception extension severely degrades any container's performance. (Unity, for example, does not recommended it for new development). I once sent you a PR with removed interception, but you added it back.

If you insist on testing interception, perhaps you could test it as a separate case and load the extension only for interception benchmarks? Right now you are loading it for all tests and slow container down by order of 2 or 3.

This issue affects all containers with support for interception and skews results in favor of containers without the interception support.

To demonstrate my point here are few numbers:

This is how for your benchmark setup by default:

Unity 5.11.7                                 Single      Multi
 Singleton                                      166        105
 Transient                                     1092        582
 Combined                                      2651       1388
 Complex                                       6600       3407
 Property                                      6690       3536
 Generics                                      6119       3173
 IEnumerable                                  12140       6706
 Conditional                                   2337       1222

and this is benchmark with disabled interception:

Unity 5.11.7                                 Single      Multi
 Singleton                                      202        112
 Transient                                      270        159
 Combined                                       945        540
 Complex                                       2955       1608
 Property                                      3137       1672
 Generics                                      2501       1320
 IEnumerable                                   4255       2655
 Conditional                                    599        338

The difference is quite significant.

ASP.Net Core Benchmark

With many of the containers supporting asp.net core out of the box it would be interesting to see a benchmark to represent a request.

I think it would be something like

  • Resolve IServiceScopeFactory

  • Call IServiceScopeFactory.CreateScope

  • Resolve ISingleton1,2,3 services

  • Resolve Transient disposable that is dependent on a hierarchy similar to Complex but use a singleton per request lifestyle vs singleton

  • Dispose IScopeProvider

  • at the end check to make sure everything is disposed correctly and counts for singleton per request.

I'd be willing to write the test and setup adapters that have published nuget packages for Microsoft.Extensions.DependencyInjection.

The original child container test isn't meant to cover this type of use case and isn't representative of ASP.Net Core per request.

Thoughts?

Update README.md

Please, can you commit/push the newest README.md that matches the results on your blog? :)

Build issue: Cannot restore packages in latest version

Hello, trying to build fresh repo checkout of version e9365e6.

Packages cannot be restored because of this error:

NU1608: Detected package version outside of dependency constraint: Ninject.Extensions.ChildKernel 3.2.0 requires Ninject (>= 3.2.0 && < 3.3.0) but version Ninject 3.3.4 was resolved.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.