IoC Container Benchmark - Performance comparison
In this post I will do a performance comparison of the most popular IoC containers.
Of course performance is not the only criteria when choosing a container for a project. Perhaps you need features like interception or you develop for a specific platform, then not all containers are suited. But especially in high-load scenarios like a web application, a fast container can help you to serve more requests in the same time, so why not choose the fastest one?
The test setup
The contestants
The number of available DI containers is quite big (see table below). Some of the mature frameworks like Ninject or Unity are widly used but are pretty slow.
Most of the younger containers offer a better performance. Internally most of them use compiled expressions to improve the resolve times.
The test setup
Several benchmarks are executed to test the performance of the containers in different scenarios.
Every container is initialized with a couple of interfaces and their corresponding implementations. The types are registered with different lifetimes to support the various benchmarks.
Every interface is resolved 500.000 times during the benchmark and the time is measured in milliseconds. Each test is executed single threaded and multi threaded.
The benchmarks:
- Singleton: Objects with is singleton lifetime are resolved
- Transient: Objects with is transient lifetime are resolved
- Combined: Objects with two dependencies (singleton and transient lifetime) are resolved
- Complex: Objects with several nested dependencies are resolved
- Property: Objects which require property injection are resolved
- Generics: Objects with a generic dependency are resolved
- IEnumerable: Several objects that implement the same interface are resolved
- Conditional: Objects with a conditional dependency are resolved
- Child Container: Objects are resolved trough a child container
- Interception With Proxy: Objects with a dynamically generated wrapper are resolved
- Prepare And Register: Initializes container and registers some basic elements (executed 3.000 times)
- Prepare And Register And Simple Resolve: Initializes container and registers some basic elements. The resolves two objects (executed 3.000 times)
The results
Overview
Container | Singleton | Transient | Combined | Complex | Property | Generics | IEnumerable | Conditional | Child Container | Asp Net Core | Interception With Proxy | Prepare And Register | Prepare And Register And Simple Resolve |
No | 41 49 | 49 59 | 69 76 | 99 103 | 186 134 | 70 75 | 193 176 | 53 63 | 644 596 |
| 469 438 | 2
| 2
|
abioc 0.8.0 | 26 43 | 33 56 | 51 82 | 67 78 |
|
| 799 506 |
|
|
|
| 6327
| 6556
|
Autofac 6.1.0 | 702 499 | 882 597 | 2369 1492 | 7249 4391 | 7216 4433 | 2119 1390 | 7780 4789 | 1766 1138 | 95939* 83541* | 40409 35736 | 22350 12007 | 651
| 682
|
Caliburn.Micro 1.5.2 | 465 270 | 533 322 | 1583 906 | 7403 3712 | 9157 4733 |
| 5965 3393 |
|
|
|
| 55
| 56
|
Catel 5.12.11 | 232 282 | 3883 4263 | 9072 9828 | 21140 22450 |
| 8668 9519 |
|
|
|
| 3819 4186 | 9916
| 9346
|
DryIoc 4.7.2 | 61 58 | 93 79 | 93 111 | 115 115 | 161 180 | 221 143 | 678 670 | 257 214 |
| 2979 1308 | 1283 1451 | 101
| 85
|
DryIocZero 4.0.0 | 110 96 | 88 89 | 98 105 | 220 169 | 294 205 | 92 92 | 302 229 | 380 270 |
|
|
| 0
| 1
|
Dynamo 3.0.2 | 95 70 | 104 86 | 207 158 | 685 381 | 828 455 |
|
|
|
|
|
| 16240
| 16527
|
Grace 7.2.0 | 29 39 | 42 59 | 58 81 | 77 82 | 134 113 | 55 78 | 296 242 | 58 83 | 61817* 37329 | 759 815 | 1287 764 | 234
| 1340
|
Lamar 5.0.0 | 70 70 | 163 87 | 100 115 | 129 118 | 91 96 | 98 112 | 558 385 |
|
| 4685 4364 |
| 2285
| 2849
|
LightInject 6.4.0 | 46 47 | 45 57 | 88 99 | 153 143 | 185 150 | 61 77 | 294 239 | 384 285 |
| 2268 1643 | 1548 1062 | 131
| 1686
|
Maestro 3.6.5 | 410 312 | 404 307 | 652 477 | 1547 1204 | 4824 3118 | 472 354 | 1400 942 |
|
| 12236 10304 | 6134 4361 | 149
| 162
|
Mef 4.0.0.0 | 22679 11820 | 37640 25052 | 57462 68730* | 112712* 131716* | 124500* 133833* | 137086* 114221* | 97231* 100896* |
|
|
|
| 17
| 2299
|
Mef2 5.0.0.0 | 259 178 | 252 192 | 355 263 | 657 444 | 1431 1012 | 290 226 | 1343 895 |
|
|
|
| 4715
| 6984
|
MicroResolver 2.3.5 | 25 39 | 34 59 | 55 77 | 92 89 | 39 62 |
| 262 195 |
|
|
|
| 27322
| 67518
|
Microsoft Extensions DependencyInjection 5.0.1 | 73 67 | 103 86 | 126 115 | 146 120 |
| 121 100 | 359 254 |
|
| 3934 2551 |
| 27
| 35
|
Microsoft.VisualStudio.Composition 16.4.11 | 9074 4916 | 13891 9399 | 19760 14962 | 57910 51972 | 44285 31830 |
| 42023 35658 |
|
|
|
| 7904
| 8540
|
Mugen MVVM Toolkit 6.5.0 | 102 138 | 409 715 | 2052 2590 | 9348 11352 | 436 705 |
| 9749 7094 |
| 4370 3103 |
|
| 15
| 19
|
MvvmCross 7.1.2 | 240 281 | 1470 1585 | 3607 4008 | 10040 11160 | 1448 1642 | 7519 8328 |
|
| 5508 3588 |
|
| 11
| 16
|
Ninject 3.3.4 | 3473 2563 | 8686 6969 | 23529 17635 | 63579* 49285 | 62765* 47908 | 24256 15895 | 64193* 49074 | 19294 12954 | 73303000* 50234113* |
| 20215 15029 | 130706*
| 126470*
|
Rezolver 2.1.0 | 121 100 | 137 126 | 194 171 | 328 238 | 520 385 | 183 145 | 669 408 |
| 9589857* 5697265* | 86587* 56374 |
| 20835
| 27706
|
SimpleInjector 5.2.1 | 58 66 | 78 84 | 124 114 | 152 116 | 271 202 | 90 95 | 634 415 | 109 92 |
|
| 5457 3398 | 735
| 3327
|
Singularity 0.18.0 | 24 39 | 39 59 | 66 82 | 76 84 |
| 54 80 | 241 193 |
|
| 631 652 |
| 314
| 874
|
Spring.NET 2.0.1 | 950 987 | 9711 11447 | 26941 23873 | 74745* 57777 | 52419 51992 |
|
|
|
|
| 43647 43419 | 25014
| 24884
|
Stashbox 3.5.0 | 35 42 | 63 69 | 69 96 | 86 86 | 123 117 | 66 73 | 278 213 | 62 70 | 336256* 224444* | 1461 1088 | 835 562 | 66
| 582
|
StructureMap 4.7.1 | 1121 717 | 1281 856 | 3410 2166 | 8312 6052 | 8697 5284 | 2271 1460 | 8399 5170 |
| 3215578* 1887211* | 65269* 41725 | 7859 4464 | 1325
| 7389
|
Unity 5.11.10 | 216 148 | 1443 835 | 3326 1995 | 9503 4739 | 9045 5814 | 9842 6443 | 17755 12048 | 3547 2046 | 147355* 74313* | 61350* 39009 | 56226 31096 | 122
| 287
|
Windsor 5.1.1 | 461 333 | 1839 1127 | 8062 5972 | 19313 13001 | 40830 22225 | 15542 9318 | 19361 10763 |
| 242149* 176823* |
| 18018 8775 | 2949
| 3445
|
ZenIoc 1.0.1 | 306 198 | 267 188 | 674 440 | 1809 1103 | 264 195 | 276 209 | 704 488 | 314 222 | 602490* 471765* |
|
| 77
| 964
|
Zenject 8.0.0 | 479 448 | 1370 1070 | 3689 3065 | 11142 10106 | 15829 13135 | 9021 6513 | 17932 12687 | 3082 2428 | 22250 18595 |
|
| 199
| 201
|
Basic features
Advanced features
Prepare
Feature comparison
|
Performance |
Configuration |
Features |
Environment |
Container |
|
Code |
XML |
Auto |
Autowiring |
Custom lifetimes |
Interception |
Auto diagnostics |
.NET |
SL |
WP7 |
WP8 |
WinRT |
.NetCore |
AutoFac |
Average |
Yes |
Yes |
Yes |
Yes |
No |
Yes
|
No |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Caliburn.Micro |
Average |
Yes |
No |
No |
Yes |
No |
No |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
Catel |
Average |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
DryIoc |
Fast |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Dynamo |
Fast |
Yes |
No |
Yes |
Yes |
Yes |
No |
No |
Yes |
No |
No |
No |
No |
No |
Grace |
Fast |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
No |
Yes |
Yes |
Yes |
LightInject |
Fast |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
No |
Yes |
Yes |
No |
Yes |
Yes |
Yes |
Maestro |
Average |
Yes |
No |
No |
Yes |
Yes |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
MEF |
Slow |
Yes |
No |
No |
Yes |
No |
No |
No |
Yes |
Yes |
No |
No |
Yes |
No |
MEF2 |
Fast |
Yes |
No |
No |
Yes |
No |
No |
No |
Yes |
No |
Yes |
Yes |
Yes |
No |
Microsoft Extensions DependencyInjection |
Fast |
Yes |
No |
No |
Yes |
No |
No |
No |
Yes |
No |
No |
No |
No |
Yes |
Mugen |
Average |
Yes |
No |
No |
Yes |
Yes |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
Ninject |
Slow |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
No |
Yes |
Yes |
Yes |
No |
Yes
|
No |
Rezolver |
Average |
Yes |
No |
No |
Yes |
No |
No |
No |
Yes |
No |
No |
No |
No |
Yes |
SimpleInjector |
Fast |
Yes |
No |
Yes
|
Yes |
Yes
|
Yes
|
Yes
|
Yes |
Yes |
No
|
Yes |
Yes |
Yes |
Spring.NET |
Very slow |
No |
Yes |
No |
Yes |
No |
Yes |
No |
Yes |
No |
No |
No |
No |
No |
Stashbox |
Fast |
Yes |
No |
No |
Yes |
Yes |
No |
No |
Yes |
No |
No |
Yes |
Yes |
No |
StructureMap |
Average |
Yes |
No |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
Yes |
No |
Yes |
Yes |
Unity |
Average |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
Yes |
Yes |
No |
Yes |
Yes |
No |
Windsor |
Average |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes |
Yes
|
Yes |
Yes |
No |
No |
No |
No |
Conclusion
Ninject is definitely the slowest container.
MEF, LinFu and Spring.NET are faster than Ninject, but still pretty slow.
AutoFac, Catel and Windsor come next, followed by StructureMap, Unity and LightCore. A disadvantage of Spring.NET is, that can only be configured with XML.
DryIoc, LightInject and Simple Injector offer a very good performance combined with support for advanced scenarios like interception and generic decorators. They also provide extensive documentation and support all important platforms.
Last update
07.02.2021
Source code
Latest source code is available on Github.
Downloads
Feedly
Tweet
Related posts
Tarmo Pikaro
2/20/2022
Container no - originally I through it was no container, meaning just some replacement / stub - but then I've took git clone and find out that "container no" actually stands for manual container implementation, based on IocPerformanceDictionary (http://blog.teamleadnet.com/2012/07/ultra-fast-hashtable-dictionary-with.html).
In your conclusion - you give some recommendations on which containers to use or not to use - but I guess if application requirements are not so complex and you don't need autofac/dryloc/simpleinjector advanced API - then better to go without any complex container - just have manual implementation in similar manner to your no container ?
Daniel
4/11/2020
@Zdenek:
When I introduced .NetCore column several year ago, Unity did not yet support .NET Core.
Zdenek Sery
4/10/2020
https://www.slunecnice.cz/autori/zdeneksery/
I use Unity on .net Core 3.1. without problems. I do not understand the No classification in row .NetCore.
cam
4/9/2018
Thanks for keeping this up to date! Really appreciate it.
Raj
4/1/2018
SimpleInjector supports ASP.NET CORE but looks like you have omitted it from performance comparison results.
Daniel
2/27/2018
@LZ:
Support is already there, but installation via Nuget fails in VS 2017. Therefore it is currently disabled:
https://github.com/danielpalme/IocPerformance/blob/master/IocPerformance/Adapters/TinyIOCContainerAdapter.cs
LZ
2/27/2018
Can you also please add the tinyioc container? You can find it here:
https://github.com/grumpydev/TinyIoC
Daniel
2/27/2018
@Thiago Silva:
No, I don't plan to invest much more time in this benchmark.
But you can add support for "BlueMilk" and send me a PR on Github.
Thiago Silva
2/26/2018
Any plans to add BlueMilk to the list?
BlueMilk is the "replacement" IoC container for StructuredMap, built by SM's original creator, Jeremy Miller (https://jeremydmiller.com/2018/01/16/introducing-bluemilk-structuremaps-replacement-jaspers-special-sauce/)
jcruiz
2/17/2018
It's great to have this always up to date article!
Thank you very much!
Andre
1/29/2018
Hello,
I think this is a great article. Thank you very much for it.
The feature comparison says Ninject does not support Interception.
I think they have a package for this:
https://github.com/ninject/Ninject.Extensions.Interception
Vladimir
11/9/2017
Hi! Thanks a lot for the wonderful post! I'm deciding which container to use on my project and surely this will help a lot to make this decision! Just wanted to clarify: you've mentioned in updates for example you've added TinyIoC, but I see it only in results archives (Downloads section), not in the post itself. Do you plan to update the post too, or it's better to look for new results in archives? Thanks!
Tamer Ahmed
10/24/2017
Daniel
10/24/2017
@Tarmer:
I don't have plans to do so.
But Xamarin supports .NET Standard. So every container that is NET Standard compliant, should work in Xamarin.
Tamer
10/24/2017
Hi,
First, Thank you for your topic it's very good and helpful.
Is there any chance that you add Xamarin as an Environment ?
Thank you again.
Jakub Jedryszek
8/31/2017
https://jj09.net
Looks like MEF2 is available on .NET Core: https://weblogs.asp.net/ricardoperes/using-mef-in-net-core
Dzmitry Lahoda
8/2/2017
I have never used `abioc`. But it has only five starts, only few month of history, nointegrations, 1 contributor, less than 1000 nuget downloads, etc. Such projects, from my observations, are not usable or will be dust in few years.
dzmitry.lahoda
8/1/2017
How to make this bench more correct and more truthful and easier to maintain?
I think some limitation on what containers could be added should be done. As example `abioc`. It got fast, but is it useful? I mean it may mislead to be fast, but really not useful. If it not useful, it adds burden to maintain longer list of containers in code of bench, hard to change bench in future. Also it may mislead overall results. I suggest drop containers with to few starts/downloads/etc from master to ensure we got possible useless bench results. `abioc` IoC is the case.
Another possible way to decrease list of containers and make timing less misleading add
1. Real world like graphs. E.g. possibly typical backend HTTP applicaion with 100 of registered classes. Some of these are resolved depending per request headers. Another option is console app.
2. Add parallel tests. Moderns computers has many cores. We should see what containers do behave well when many threads calls them.
I think these tests will change view of fastest to be much more correct.
And last thing. You may find that there are standards ways to measure perf on .NET now. I think migration of this bench using them will make this bench more extensible, lead to unified bench .NET mode in future. And may be finally some stuff of DI/IOC will got into BCL.
Meysam Khoshbakht
7/2/2017
please check castle Windsor
OJ
3/18/2017
http://www.ojdevelops.com
Thank you for this benchmark. It influenced my decision to use SimpleInjector in my projects. Working great so far.
Juan
10/29/2016
Awesome work thanks :)
I am trying to find a container that supports interception on UWP. You have the interception and platform columns in your feature comparison, however it does not indicate if a feature such as interception is supported on all/any platform. Could be a nice little detail ;)
Arthur Minduca
10/18/2016
https://arthurminduca.com/
I just want to thank you for the updates you make in order to keep the statistics up to date. I still use your article for reference when choosing a container for the next project.
Great work
Daniel
10/4/2016
@Nick
Both Unity and Autofac are listed in the "Prepare" chart. But not in the two other charts ("Basic features" and "Advanced features").
If you download the Results.zip you will get detailed results and charts for all containers.
Nick
10/4/2016
Hi Daniel,
thanks for the fast reply. Hmm but i dont really get it. When you check the table with the timings, autofac is faster then unity. But unity is listed in the charts and autofac not.
Daniel
10/4/2016
@Nick:
The charts only includes containers that are fast enough.
The header shows which maximum total time is "allowed".
Nick
10/4/2016
http://fremdwortdestages.de
Hi Daniel,
is it possible that the graphics aren't up to date? Autofac is not part of the list. Just wondering why.
BR
Daniel
8/14/2016
@Ajith:
I don't know, why your machine is that slow. Do you have you have any other running processes?
I don't have plans to add licensing information to the table.
Ajith
8/10/2016
Daniel, Could you please add a column with licensing information such as open source or commercial etc.
Ajith
8/9/2016
Hi Daniel, Thanks for the informative article on DI. In the DI arena there is no better article than this. I am curious to know what is "No" , is it custom DI if yes why you are not recommending it?
I have downloaded the code from github and able to run. it has been running for the past 2 hours....(it started micro silver) still it is progressing....
WHy there is huge difference in my result as compare to your result...it is 4 times higher than you.
my laptop configuration is i7, 8GB, 1tb, etc.
Thanks
Adam Stephensen
7/25/2016
http://www.ssw.com.au
Hi
Great post!
I have linked to it on https://rules.ssw.com.au/do-you-know-the-best-dependency-injection-container-(aka-do-not-waste-days-evaluating-ioc-containers)
A post on performance like this is awesome, but from the URL it looks like it was last looked at 6 years ago in 2011.
A suggestion would be to move your update notes from the bottom of the page to the top of the page as per https://rules.ssw.com.au/do-you-know-to-update-a-blog
Daniel
5/11/2016
@matheiu:
I did not yet think about Xamarin and UWP.
What do you want to script? The update process is quite simple:
1) Retrieve new Nuget packages
2) Run IocPerformance.exe -update
matheiu
5/7/2016
Hi, its seems the most complete benchmark of containers. Thanks for the work. Do you think you might do updates with new versions of containes and with UWP and Xamarin new contexts ?
Maybe we might script this benchmark so it updates simply ?
Jörg
4/28/2016
StructureMap doesn't support XML anymore since version 3. So the "yes" in the feature comparision table is a little bit misleading.
Internet Marketing
2/18/2016
http://www.saganmarketing.com
It would be useful if you also included whether or not they support .NET Core/MVC 6 as this is an important consideration these days.
DryIoC documentation
1/14/2016
http://xmedeko.blogspot.com
DryIoc has improved the documentation, see https://bitbucket.org/dadhi/dryioc/wiki/Home
Joao Grassi
1/9/2016
This is a great post, thank you! We use Castle in most of out MVC and API projects and I'll certainly look for other alternatives!
Jan
12/22/2015
I see LightInject disappeared from the overview.
Ivan
12/8/2015
http://bananaqualitytester.blogspot.co.uk/
Thanks for the post, Daniel!
Peter
11/5/2015
Microsoft.Framework.DependencyInjection is missing in the Features table?
Thanks for a great post!
Daniel
10/6/2015
@Richard:
I plan to add the container of ASPNET 5.
If you like, you can also send me a pull request on GitHub.
Richard H
10/5/2015
Would it be possible to use the built-in DI in ASPNET 5 against these tests? I realise that it is still an early build but it would be great to get an indication of how it performs in relation to the others, to see whether it is worth substituting one of the other IoCs in.
Yura
9/14/2015
Please add SimpleIOC from MvvmLight toolkit
Ben Stabile
9/5/2015
http://deltacodec.codeplex.com
Thanks for maintaining this. It is very illuminating.
I would like to point out that containers such as Unity (and some of the other full-featured ones) are often used in very complex projects where the additional capabilities are important.
In enterprise systems it is often vital that the dependency injection integrates well with other sophisticated frameworks such as Prism and Enterprise Library. Sure, we're developers so we can almost always get anything to work with anything else. But at what cost?
Another thing I would like to point out is that MEF really falls into another category than most of the others. I mean, it is, after all, designed for providing Extensibility, and not just for Inversion of Control, or Service Location.
MEF can be used for DI without too much pain. But can you imagine some poor soul trying to use MAF (Managed Add-in Framework) for the same purpose? Yikes!
On at least one large Prism project I've used Unity, MEF (in plug-in modules), Prism, Enterprise Library, and a few other frameworks together. It actually worked out quite well and I can't imagine trying to solve the complexities we faced without the built in support.
I also had a project that required mixing MEF, MAF, Unity, and Enterprise Library. Again, I was glad for the native support integrating these frameworks.
My point, as someone else pointed out, is that speed isn't everything. But it sure is nice that you've gotten a handle on how these various tools perform.
Cheers!
Raj
9/4/2015
Thanks for keeping this benchmark up to date over the years!
Jonathan
8/27/2015
I'd love to see MvvmCross's IoC container added to the list. I am a C# Web/Xamarin developer and I am currently evaluating MvvmCross and Mvvm Light as potential frameworks. I noticed MvvmCross has IoC baked-in, but I haven't found much information related to its overall performance, just some generalities.
Reference:
https://github.com/MvvmCross
Chris
8/25/2015
Have you tested the version of Funq that ServiceStack uses? I would be interested to see how it stacks up.
Ra
8/10/2015
Thanks for keeping this benchmark up to date over the years!
Daniel
7/14/2015
@Søren:
If Windsor is fast enough for you, there's no need to change the container.
But it would be interesting to see what happens to the average request processing time, if you use a fast container.
Perhaps you want to start an experiment?
Søren Skov
7/14/2015
http://dataloghuset.dk
Greate article!, but according to your resume text:
"But especially in high-load scenarios like a web application, a fast container can help you to serve more requests in the same time, so why not choose the fastest one?"
I need to know if you can think of a maximum time limit for some of the framework operations in a website application? (for a professional experience with a midsized company with a few thousand visitors per day)
or simplyfied, do you personally think Windsor is too slow in that web context?
I have used Windsor in big web projects earlier where initialization is done once in Application_Start (asp.net) and no one has complained after that. Now starting up another web project, it better be the best choice! :)
Thanks in advance and BR
Michael
6/21/2015
Interesting analysis. Reading the numbers on the whole, I'm still not a "fan" of MEF, per se. I used to think Ninject was okay, but the numbers are there and tell the story. At the time my interest in Ninject was cross platform, for .NET (desktop) and .NETCF. I'm not sure the analysis also takes into account readily available extensions, or other improvements; it has been several years, after all, since the OP; i.e. I'm pretty sure Ninject does support things like interception, via extensions and such. I would be curious what the libraries all offered in terms of isolation, one module/kernel to the next.
Luiz Freneda
6/3/2015
Stefano
5/18/2015
Thank you Daniel, nice post!
Could you also try to compare all these IoC from the usability/friendlisness point of view? I think it's a very import aspect!
dadhi
5/15/2015
https://bitbucket.org/dadhi/dryioc
@Brannon,
As I know Castle Winsdor and DryIoc v2 has support of Per-object-graph lifetime. It may be good idea to create corresponding issue or provide PR to http://featuretests.apphb.com/DependencyInjection.html
Brannon King
5/13/2015
I would be interested to know which frameworks support per-object-graph lifetimes.
Mark Rowe
4/21/2015
SimpleIOC in mvvmlight? I mainly use this but I'm stuck in a applications (wpf) only world
Daniel
2/24/2015
@Uladzimir:
Good question. There are several explanations:
1) External: Process is interrupted by another process
2) Internal: The CLR is not deterministic, e.g. Garbage Collection can happen all the time.
You could try to find out by attaching a profiler, but that will change the results too.
Uladzimir
2/24/2015
Hi,
I faced with situation that IoC perfomance solution have unstable results.
Could you please explain, why results can differ from each other when running you tool more than 10%?
For example, autofac test run:
1 time Singleton Combined - 4601
2 time Singleton Combined - 5920
3 time Singleton Combined - 4746
(Build- Release. Win12kr2, 8CPU, 16GBRAM)
Each test was run from cmd and executed separeatly.
Thanks!
Evan
1/17/2015
@Daniel
Good work any way.
@Dzmitry.Lahoda
I appreciate the url quiet useful.
Dzmitry.Lahoda
1/9/2015
@Jimmy,
I you used Unity then may try "QuickInject is a Unity 3.5 based IoC container that aims to give the Unity container a performance advantage in basic scenarios." and report if this helped.
Jimmy
1/7/2015
http://www.componentpro.com/saml.net/
I experienced Unity's performance issue and I came across dis article, which is so good. I will give light IOC a try for our system.
Dzmitry.Lahoda
1/5/2015
I found next 2 issues:
1. NoContainer is not "no conainter", but DictionaryWithCtorFunctions with some object lazy and some eagerly created. More real NoContainer may be switch statement with all Lazy creation (what containers create on registrations?). Renaming NoContainer into will DictionaryWithCtorFunctions be fine.
2. Prepare is unfair regarding feature rich containers. I.e. feature rich container registers some extensions and more types then poor one, leading poor one behave better. Right is to compare Basic registrations for all containers until special feature required.
Dzmitry.Lahoda
1/5/2015
@Evan, this info seems better suited for http://featuretests.apphb.com/DependencyInjection.html.
Daniel
1/5/2015
@Evan:
One could of course introduce a lot of metrics. But everybody has different requirements and preferences.
And I a don't have the time to collect all the information for 33 containers and keep the data up to date.
Evan
1/4/2015
It is irrelevant how fast or slow it is if it does not work very well or there is no indication about it.
It would be be very constructive if you had a stability/reliability factor or include number of current bugs, number of downloads, last release date, number of months in production.
Ph.Tp
11/7/2014
Could you update your benchmark with the latest versions of containers, please?
Andrew
8/26/2014
What is it the Auto column at the feature section?
Mick
8/21/2014
Nice work. But really, who injects half a million objects? I think in a typical web request in our system which uses NInject we would make between 10-100 injections. Your article is thorough but in a sense misleading as it makes people focus on something that for 99.99% of the people out there is a complete non-issue.
I think some time ago a really smart programmer such as yourself pointed out the difference in execution speed of virtual methods versus static methods on static classes. The result is he has doomed generations of average to sub-average developers to never writing OOP code.
Federico
8/18/2014
http://thepiratblog.blogspot.com
Excellent article!
I think you should change the value of column "Auto" for the row "MEF 2", since it does provides auto-wiring.
Mac
7/28/2014
Probably a dumb question, but what are the two numbers listed for each test? Registration vs resolution, maybe?
Malachi Burke
7/19/2014
Ian Johnson
6/21/2014
https://github.com/ipjohnson/Grace
S,
Simple Injector doesn't support keyed registration, look at comment #35 from the author simple injector. He refers to it as a "code smell" and therefore doesn't support it.
Most everything with Simple Injector is offered as code add on later that you include in your application, hence no NuGet package.
If you are looking for a fast container that does support keyed registration check out Grace. It has a very large feature set and has good performance.
-Ian
Daniel
6/20/2014
@S: It's an extension: https://simpleinjector.codeplex.com/wikipage?title=Advanced-scenarios#Context-Based-Injection
S
6/20/2014
Is that method an extension method that's part of a separate assembly or perhaps obsolete? I can't find it and I'm using the latest version of SimpleInjector from http://www.nuget.org
Daniel
6/20/2014
@S:
I don't sure what you mean with "keyed registration". Do you mean registering a component with a custom name?
In case you are using SimpleInjector you can use RegisterWithContext() method. I think that approach is preferable to named registrations, otherwise you have to explicitly request the named component.
s
6/18/2014
One of the features that doesn't seem to be part of the comparison is keyed registration. I could see why it would be overlooked, thinking that any/every IoC container would support that, but that's definitely *not* the case. If you're looking to switch from one IoC to another it's important to know. Especially since this post seems to be touting SimpleInjector as one of the best in terms of performance and advanced scenarios when it doesn't even support one of the most basic scenarios! Sorry to pick on SimpleInjector, but that just happens to be the one that I was looking at.
Daniel
6/18/2014
@Michael:
Autofac allows you to scope objects, but I'm not aware of a possibility to create a custom lifetime. Can you point me to some documentation?
Michael Tsai
6/16/2014
Hi Daniel,
Would you further explain why you think Autofac does not support custom lifetime management?
Thank you for the awesome work!
Daniel
6/13/2014
@Robert:
I tried to use logarithmic scale in the overview charts, but comparision is much harder then.
Individual graphs are generated for each benchmark, but they are not published on my blog. Feel free to run this on your machine:
https://github.com/danielpalme/IocPerformance/blob/master/IocPerformance/Output/ChartOutput.cs
Robert
6/13/2014
And it would also be much better if you didn't use stacked bars in the "Advanced features" as not all bars include all features. Each feature should be a separate graphs so one could compare on individual ones (and those that are missing).
Robert
6/13/2014
Why don't you rather change graph scale to logarithmic. It would be easier to distinguish graph details of both the slow ones and quick ones.
Hakan
5/10/2014
LightInject can support context per request?
for implement unit of work
Daniel
5/6/2014
@William:
The results table already shows the latest Unity release (version 3.5.1404.0)
William Ziebell
5/6/2014
https://twitter.com/WilliamZiebell
Grigori Melnik from Microsoft blogged on Apr. 21, 2014 that Unity 3.5 RTW was released. He stated that, "In running micro-benchmarks, we have consistently seen a performance improvement of Unity core operations by ~60%." It would be nice to see the Final Release version benchmarked here.
Also, this version of Unity is now a portable class library with support for Xamarin/Mono (Xamarin.iOS v7 and Xamarin.Android v4.12). Perhaps a column for Xamarin Support in the Feature comparison is now in order.
Wayne Blackmon
4/30/2014
I just tried out both SimpleInjector and LightINject in an ASP.NET Web API (MVC 5, Web API) application (along with recommended Web API and MVC 5 libraries). SimpleInjector caused a yellow screen of death (it seemed to conflict with System.Web.Http) and LightInject actually corrupted the project file and caused the application to not load in Visual Studio 2013. Both SimpleInjector and LightInject just didnt work with MVC 5 and Web API 2.
I rolled back the project and installed Unity. No problems with Unity.
Tristan
4/19/2014
Since 2.4 Simple Injector support WP8 and winRT
It also supports Mono which is great with the rise of Xamarin.
Mike
3/21/2014
Mine of course (IfInjector) - LOL!
Actually, the first three questions you should ask are:
1. What features do you need?
2. What platforms do you need to run on?
- If you need to run on something exotic like Xamarin / iOS, a legacy version of Windows Phone or XBox. This dramatically alters the list of options available.
3. How performance sensitive are you?
- Do you need something that create instances of objects quickly OR are you just wiring up a bunch of singletons? In the latter case, the performance listed here becomes less important as it is a one-time overhead cost... although it can still be a painful drag on your unit tests.
==========
Beyond this you want to go with something that is well supported and documented. Dependency injection is not that complicated so the complexity is (in general) not that different between containers for the basics. When you get down to the complex features though - the documentation will be the difference between a simple and an easy task.
At least from the ones I have looked at, SimpleInjector seems to hit the sweet-spot of top tier performance and good documenation AS well as having a great story around customization and extensibility to meeting a variety of use cases. Ninject, while slower, has versions to run on a wider variety of platforms and has a great community / documentation. On iOS all of these benchmarks would be moot anyhow.
Take a quick peak through the docs of the containers that meet your performance / platform requirements - then go with the one with the best documentation.
JP
3/6/2014
Which of these is the easiest to learn & implement?
dadhi
1/13/2014
https://bitbucket.org/dadhi/dryioc
Hi Mike,
Please go ahead and use. It is interesting to see how it adapts.
As for accreditation, I probably put HashTree separately into Github or Bitbucket under MIT license. So you can include link when it's done.
P.S. You can contact me through my bitbucket or github accounts.
Mike
1/11/2014
https://github.com/iamahern/IfInjector
Hi Dadhi,
I apologize, but I can't find another way to contact you.
I plugged your AvlTree into my SafeDictionary class and it worked great. Any issue if I reuse your implementation in IfInjector?
If it is ok, what sort of accreditation line would you like?
Mike
dadhi
1/10/2014
https://bitbucket.org/dadhi/dryioc
Ian,
Register and Resolve could be done concurrently. Registry consistency is preserved with single SyncRoot locking.
When you resolve service, delegate is cached in tree which is immutable which enables lock-free access.
Regarding container change there are so many aspects to that, but in general case newly added registrations won't affect already resolved/cached delegates. Which is fine I think. If you need you could resolve services as Many<T> which is aware of new registrations or use subcontainer for resulution and then drop it to drop the cache. I am planning to write on this topic in wiki.
There is also plan to introduce cache skip policy in Resolve in future versions.
Ian Johnson
1/9/2014
http://grace.codeplex.com
Dadhi,
Very interesting. Do you allow the container to be modified as it's being used? If so how are you handling concurrency?
dadhi
1/9/2014
https://bitbucket.org/dadhi/dryioc
Valy, Ian,
What I wanted to say that AVL tree implementation in DryIoc serves to speedup access to resolution roots, not all of the registered services. The rest of registry uses Dictionary internally.
Anyway tree performance degradation is not that big. Here the results of my benchmark:
Comparing worst case of lookup for item in tree with normal access to dictionary 1 000 000 times (it is Type to Object for both):
for 20 items: Dict - 37ms, Tree - 10ms
for 2000 items: Dict - 37ms, Tree - 18ms
In addition I want to say that tree is not the only thing to improve performance, there are other things as well.
Ian Johnson
1/8/2014
http://grace.codeplex.com
Hi dadhi,
I think Valy's point was that as more types are registered you're performance will degrade. Which is going to be true for all lookup containers not just tree structures. It's just that you will lose that performance benefit when the tree is loaded with more entries.
Personally I don't see a problem with it, this is just a general guideline tests and you need to look at your individual use cases and see if a container will work well for you. It really doesn't matter if the container uses trees, dictionaries, or arrays as long as it meets your needs.
That being said always pay attention to feature set and configuration when choosing a container.
-Ian
dadhi
1/8/2014
https://bitbucket.org/dadhi/dryioc
Hi Valy,
Take into account that services directly resolved from Container are usually resolution roots, that is a small subset of all registered services.
Here I am assuming Container usage mostly avoiding Service Locator (anti)pattern.
In that case DryIoc performs just fine by given fast access to resolution roots.
Valy
1/5/2014
DryIoc use an AVL tree instead of a dictionary that performs better for small size services. So I don't think the comparison is fair enough.
Ivan
11/24/2013
Daniel, please change value to Yes in Interception Column of Feature Comparison table for LightInject container, because it have this feature. Proof: http://www.lightinject.net/# (Interception link on top)
Ian Johnson
11/17/2013
http://grace.codeplex.com
@Ashley
While performance for a DI container is important, feature set and configurability are also very import when choosing which container to use.
I think it's really interesting to look at Daniel's performance tests in-conjunction with the feature tests located at http://diframeworks.apphb.com/
It's a matter of balancing the features you want with the performance you can live with.
-Ian
Daniel
11/13/2013
@ashley wardell:
I'm sorry but I don't have the time to cover all possible details of every container.
Projects are very different so you have to make a choice yourself :-)
ashley wardell
11/13/2013
http://www.soundblitzdisco.co.uk
Hi there.
Firstly can i say this has been one of the most useful links i have found in a which. Thanks for putting the effort into this.
a few comments.
I noticed that structuremaps registry does not seem to have an equivalent in simpleinjector. Obvs. this can be custom written but would have been nice. Would be nice to know which features such as this are available on each framework.
Also out of the box lifecycles is a factor when i have decided which DI framework to use.
I wondered if you could add these pieces of functionality to this article
Thomas
10/24/2013
Great Work! Helped me a lot to decide witch IoC to use in projects!
Rajiv Mounguengue
9/6/2013
Hi Daniel, Catel supports Interception now.
Brent Roady
9/3/2013
Unity 3.0 (current release) now supports auto configuration (http://blogs.msdn.com/b/agile/archive/2013/03/12/unity-configuration-registration-by-convention.aspx), if you want to update the Feature Comparison grid.
Thanks for the excellent resource!
Daniel
9/1/2013
Ninject supports both interception and Xml config via extensions.
Christian Henrik Reich
8/5/2013
http://ww.havebox.net
Hi Mike,
Congrats, with the good result on property injections, it is going to be hard to beat:-)
Cheers,
Christian Henrik Reich
Mike
8/3/2013
https://github.com/iamahern/IfFastInjector
Hi Daniel,
Again - thanks for maintaining this. Some minor corrections to the feature tables above:
Environment/SL: Yes
Configuration/Auto: Maybe?
I am not sure how you are defining auto configuration - but you can do stuff similar to Ninjit such as:
==============
@IfImplementedBy(typeof(MyType))
interface IMyType{}
@IfSingleton
class MyType {}
....
var injector = IfInjector.NewInstance();
IMyType instance = injector.Resolve<IMyType>();
==============
With the latest updated to the benchmark push I sent you I should (until HaveBox 1.5 comes out next week LOL :-) win the property injection benchmark.
Cheers,
Mike
Christian Henrik Reich
8/1/2013
http://www.havebox.net
Hi,
I would like to point out, that HaveBox 1.4.0 is using HaveBoxProxy for interception. HaveBoxProxy, do not support functions with generics and out parameters yet.
Please have this in mind, when intercepting with HaveBox.
Cheers,
Christian Henrik Reich
Christian Henrik Reich
7/31/2013
http://www.havebox.net
Hi Daniel,
Regarding HaveBox 1.4.0, I have tried to make a pull request, but I can't see if it is sent or not.
Cheers,
Christian Henrik Reich
Mike
7/26/2013
https://github.com/iamahern/IfFastInjector
@Danial: Thanks for getting IfFastInjector up there so quickly!
Christian Henrik Reich
7/15/2013
http://www.havebox.net
Hi Jury,
I still don't know your situation or how you configure HaveBox, but if you scan your assemblies and do your batch operations in one scope, then there is no order requirements. You can even use sub-configs to organize it, and keep it maintainable. So what you are saying are not quite true.
Again HaveBox can't depend on types it doesn't know, and that it how it works. If HaveBox's configure part don't
works in the way you want it to, then there is a lot of alternative container to use, you even have your own container now, use that.
You are the only one, I have ever heard of, who has issues with the config.
HaveBox's IS production ready. Just because HaveBox doesn't fits exactly your requirements, does not make it less production ready,
it just means it is maybe not the right tool for you. Where is the line for production ready and or not? If I implements deferred dependency resolving, which you feel is missing, do HaveBox then cross the line for production ready? What if the next person, who doesn't care about deferred resolving, comes afterwards an points out xml configuration is missing, is HaveBox then on the not-ready-for-production side again? Is Unity not-ready-for-production, because it can't do generic resolving? It all comes down to features, and choosing the container which solves you problem.
By suggestion removing HaveBox from the benchmarks, is at the same low level as proclaiming that HaveBox is cheatware. It also show that you have misunderstood this benchmark page. The page shows performance for resolving, not for how the container is configured. Some of the contestants, do not even have auto-wiring, which some find basic container behaviour, should they be disallowed to? As I understand, here room for every container, which I find good.
I really don't understand, why you spend your time on HaveBox, when it is obversely not suited for you. Your time could be used much better on a project with another container, than flaming HaveBox.
Cheers,
Christian Henrik Reich
Jury Soldatenkov
7/15/2013
Hi, Christian.
Ok, I was too rude when called HaveBox cheatware. Let me explain.
The main issue with singleton is not the eager instantiating itself (still very unpleasant), but consequent obligatory registration order.
It's impossible to scan assebmlies and perform batch registration.
That's why I think you should be fair with yourself. HaveBox is not-ready-to-production-ware, and should be excluded from benchmark.
Or put it in a section "prototype races".
PS. As an exercise I've tried to write my own container, and it takes about 5 hours to make it with fair singleton and trasient support, and detect cyclic dependencies.
Resolve speed is the same as HB, but registration is longer.
Ian Johnson
7/14/2013
http://stylemvvm.codeplex.com
Hi Jury,
I don't think Havebox is cheatware. It might have a smaller feature set than some other DI containers but it's not cheatware.
I will say though that since there are some many different ways to solve these problems there are some discrepancies in the way that these things are implemented and configured. So you end up comparing containers that autowire to ones that don't. Containers that require the developer to know all Exports when registering an IEnumerable and some containers that allow the developer to register multiple implementations for one Interface and then resolves all interfaces into an IEnumerable.
You have to really look at the implementation and see what use cases it solves that you are interested in (feature set including configuration), with what type of performance you need.
I guarantee you if you went to an ninject discussion board people would run you out with data points of ninject solving their problems in a perfectly per-formant manner. So it's all about your use case ...
YMMV
Christian Henrik Reich
7/13/2013
http://www.havebox.net
It is properly not the right forum to discuss this, so Daniel I hope you will allow this comment.
@Jury Soldatenkov, regarding #57
I have been investigating Have-1.3.0 for the issues you mention, and regarding your singleton issue.
I can only reproduce it, by doing step wise configuration like this.
container.Configure(x => x.For<IFoo1>().Use<Foo1().AsSingleton());
container.Configure(x => x.For<IFoo2>().Use<Foo2>());
It is true that HaveBox-1.3.0 does resolve singletons eagerly. When the Configure goes out of scope, HaveBox builds the dependency graph, and if there is information missing it will throw an exception. This is the nature of HaveBox.
By having Foo1 with Foo2 as dependency, and then doing the stepwise configuring as above. You are telling container that Foo1 have dependencies of types, unknown to the container. The container has no chance to know your intentions, about register the Foo2 later or not. Therefore I think an exception is fair, when trying to depending on unregistered type. Lazy or eagerly singletons, I'm not sure it makes sense in general to depend on types, there is yet to be registered.
I'm sure you have your got reasons, if you have your step-wise configurations. But my recommendation is to
configure most a possibly at ones, like:
container.Configure(x =>
{
x.For<IFoo1>().Use<Foo1>().AsSingleton();
x.For<IFoo2>().Use<Foo2>();
});
Thereby order is also becoming less important.
Lazy resolved singleton is scheduled for later release. Regarding cycle dependencies, now where you mentioned it, I'll look into that too. For further discussion, you are welcome to write me at HaveBox2013@gmail.com
As last comment, I find it harsh and unfair to label HaveBox-1.3.0 as cheatware, because it doesn't fits your needs.
Cheers,
Christian Henrik Reich
Christian Henrik Reich
7/13/2013
http://www.havebox.net
Hi Jury,
I'm very glad you have spend your time testing my container.
I'm trying to make HaveBox a highly usable tool for programming, and not cheatware.
If you have found a bug, you should have raised it, via the issue system on the HaveBox page, and thereby contributing to making it a better ioc-container. I have no chance to fix the container, if I have to crawl to web for issues.
Cheers
Christian Henrik Reich
Jury Soldatenkov
7/12/2013
I've tested HaveBox 1.3 from official Nuget feed. It look like a cheatware, that could not be used really. Two main issues I found:
1. Creates singletons eagerly, at registration time. Consequently it does not handles dependencies. If class A (singleton) depends on B, you have to register B before A. KeyNotFoundException otherwise.
2. Does not handle cyclic dependencies, just throws ugly KeyNotFoundException.
Christian Henrik Reich
7/4/2013
http://www.havebox.net
Good Work, Ian Johnsen :-)
David Walker
7/2/2013
http://grax.com/
A more detailed response to comment #48 is at
http://coding.grax.com/2013/07/response-to-ffastinjector-concerns.html
The short version is: fFastInjector is not just fast, it is also small and I believe it to be very reliable. It is not very mature and I expect to be able to provide significant improvements, such as custom registrations in the near future.
I think it would be reasonable to test both the generic resolution and the type parameter-based resolution to compare the speeds of each method.
In my projects the generic resolution is the preferred method and fFastInjector is optimized for that but should actually still be extremely fast either way.
Christian Henrik Reich
6/28/2013
http://www.havebox.net
I have released HaveBox-1.3.0, which is optimized for speed.
It also has instantiation interception, as a new feature.
Cheers,
Christian Henrik Reich
Daniel
6/18/2013
@Nikhil:
There is an extension for Ninject:
https://github.com/ninject/ninject.extensions.interception
Nikhil Pinto
6/18/2013
I was under the impression that Ninject supports Interception. I have seen plenty of examples demonstrating AOP for which Interception i believe is a must.
PS: I am a novice with IOC containers ...so not really sure... can you please confirm if i am right or wrong.
Ian Johnson
6/18/2013
http://stylemvvm.codeplex.com
Hi Daniael,
I was wondering if you'd be interested in doing a Part 2 of this blog that covers more advanced cases of DI. While this is a great start I feel like a lot of your readers have far more complex DI needs, covering this like Open generics, conditionals and large object graphs would be really interesting.
I'd be more than willing to lend a hand in code some of it up. Email me back if you are interested.
thanks
-Ian
Christian Henrik Reich
6/16/2013
https://bitbucket.org/Have/havebox/wiki/Home
Hi Daniel,
I have just released HaveBox 1.2.0, besides adding new features, I have been optimizing it for speed.
Cheers,
Christian Henrik Reich
Christian Henrik Reich
6/11/2013
https://bitbucket.org/Have/havebox/wiki/Home
Hi Daniel,
I have just released HaveBox-1.1.0, and I hope you will update your page with new version.
The slow MakeGenericMethod is not needed anymore, now you can call GetInstance(Type type), and get a more realistic view from the benchmarks
Auto registration has been available since version 1.0.0 via Scan, but I have added new features:
Custom lifetime
Support for Silverlight 4, Silverlight 5, Windows Phone 7.1 and Windows Phone 8
It is available from Nuget: http://www.nuget.org/packages/HaveBox/
Cheers,
Christian Henrik Reich
Be aware
6/4/2013
Something to notice about fFastInjector is that it is static, and it is made pretty much only for speed by creating a static generic class for every registration instead of storing them in some sort of collection like all the other (it does use a collection - but only to map resolving by Type to the static generic class).
The thing is that if you use something like MVC everything is resolved using the Type and not using a generic parameter, and then the performance decreases.
So it performs very nice under the test conditions but in a real world scenario it is no different from the other fast containers, and doesn't have the same feature set and seems difficult (if not currently impossible) to extend with custom lifetime registrations (for example perRequest or perSession lifetimes for Web scenarios or perThread etc.).
I would recommend that the tests are change to resolve using the most basic way (using the Type and not Generics) to prevent this scenario.
Resolving using the generic parameter is only relevant if you are manually wiring everything up yourself, if you are using auto-wiring which I hope pretty much everybody prefer, then the Type is used.
Also if you look at HaveBox it will also perform very good in a test like this where the same type is resolved x number of times, because it stores the registration for the last resolved type so it can quickly return it. But in a real world scenario how often is the same type returned every single time? - Never.
So this is solely implemented for it to cheat in a test like this as it will be a performance decrease in any real world scenario (so what else could be the reason behind the decision to implement it like that?). Because of this I actually think it should be banned from the tests until it is changed.
Also something even more important, the way this "cheat"/cache is implemented seems to be a problem in a multi-threaded scenario where several types are Resolved at the same time by different threads - look at the method GetTypeDetails in the Container.cs - what happens if GetInstance<>() is called while another thread is in the middle of assigning those variables (the ternary operator is not guaranteed to be thread-safe) ? *BOOM* *Mis-match in the type returned and an exception is thrown*...
Have a nice day. :)
dadhi
6/4/2013
I think it will be plus to include minimal .Net Version supported into .NET column. Some containers are taking advantages of latest .Net (e.g. Expession.Block from .Net 4.0) but mine real-project requirements are .Net 3.5. So those containers are no use for me.
Karim
6/3/2013
fFastInjector seems to be a good choice too (winRT support) but no interception feature.
I Hope that Simple Injector will support WinRT soon.
PS: On your feature comparison table fFastInjector is marked as fFastContainer.
Christian Henrik Reich
6/2/2013
Hi Daniel,
Super post.
I have just released my own ioc container, which I also thinks is the fastest :-), based on my own benchmarks against SimpleInjector.
It is called HaveBox, and I would like to hear, if you can add it to you page?
HaveBox and full documentation can be found here:
https://bitbucket.org/Have/havebox/wiki/Home
https://www.nuget.org/packages/HaveBox/
Cheers,
Christian Henrik Reich
David Walker
6/1/2013
http://www.grax.com
Excellent post! I used your code to get the numbers and graphs for my post on my new fFastInjector. According to your code, it is the fastest dependency injector yet.
The post: http://coding.grax.com/2013/06/how-fast-is-ffastinjector.html
The code: https://ffastinjector.codeplex.com/
The NuGet package: https://nuget.org/packages/fFastInjector/
Daniel
3/20/2013
@Steve:
You are absolutely right, Funq only supports explicit constructor registration. That means autowiring is not supported by Funq, which is a major drawback, since you have to change the configuration every time the constructor changes.
You should use autowiring whenever possible, because that means less maintenance work.
I did not configure explicit constructors in my benchmark, when a container supports autowiring.
It's the container's problem to resolve the constructor dependencies in a fast way. And containers like SimpleInjector show, that it is possible to do this very fast.
Steve
3/20/2013
Hi Daniel,
Nice writeup - there are some pretty key variances between registrations that are impacting containers differently. Lets start at the top of the list and take autofac as an example.
Autofac registration looks like this:
builder.RegisterType<Combined>().As<ICombined>();
That call relies on reflection on instantiation to decide on the ctor to use.
Funq on the other hand looks like this:
builder.RegisterType<ICombined>( c => new Combined(c.Resolve<ISingleton>(), s.Resolve<ITransient>());
That call does not rely on reflection - in fact the ability to rely reflection is not supported by Funq, so there is a key difference.
To tidy these up, in Autofac you would register as follows:
builder.Register<ICombined>(c => new Combined(c.Resolve<ISingleton>(), c.Resolve<ITransient>());
This cuts significant time off any container that falls into this distinction.
Another key is being able to imply Func<T> based upon a registration of <T>. Most containers don't allow this, but it's a key operation for anyone doing modern Dependency Inversion. Of the ones that do support it, most are faster at Func<T>() execution compared to .Resolve<T>(), but some are actually slower. Knowing this difference and capability would be helpful. When you consider this optimization, then direct ctor registration could be helped with another level of lambda lifting.
Daniel
3/14/2013
@AceHack:
I'm pretty busy at the moment. So it will take some time to add tests for WinRT.
Testing dynamic proxy performance is a good idea. I think I will add this to the benchmark.
Could you check which containers support Windows Store Apps and/or WP8? I can then add your results to the feature table.
AceHack
3/14/2013
@Daniel: Again thanks so much for all your work, I was curious it would be great if you also add a column for if it's supported on Windows Store Apps and WP8. Also I would be very, very grateful if you would test the DynamicProxy speeds of the ones that support it.
AceHack
3/14/2013
@Daniel how about Microsoft.Composition package on nuget I linked to earlier? Can you incorporate those results? They are in the namespace System.Composition.
Daniel
3/13/2013
@AceHack:
The version 4.0.0.0 refers to the version of 'System.ComponentModel.Composition.dll'.
I already use .NET 4.5 for executing my tests. Since .NET 4.5 replaces .NET 4.0 I'm not able to compare with the MEF version that was distributed with .NET 4.0.
Changing the "Target framework" of the solution to version 4.5 does not affect the results significantly.
AceHack
3/13/2013
I'm a little confused by your MEF version numbers. I'm assuming by MEF 4.0.0.0 you mean the MEF that was included with .NET framework 4 (MEF 1.0). If so can you please test MEF 4.5.0.0 or what I would call MEF 2.0, the one that is included with .NET 4.5 as they made several decisions to increase performance by dropping features. Also as a separate test could you test MEF for Windows Store Apps? I really consider this almost a different IoC than the core framework version at lest for your tests. Thanks so much this is AWESOME!!! http://nuget.org/packages/microsoft.composition
Tim
2/19/2013
Hi Daniel,
Very nice post. I really like the ongoing updates!
I'm definitely going to look at the fast performance containers for my WP7 projects.
(I'm not sure Munq is right for WP7 though. Full project title is "Tools for ASP.NET MVC")
Cheers, Tim
Steven
2/14/2013
http://www.cuttingedge.it/blogs/steven
Martin is right, Simple Injector does not support keyed registrations. And for good reasons (http://bit.ly/Vj5epb). Keyed registrations are a design smell and if you need them, you should review your design. It's true that some containers make it impossible to implement particular features without keyed registrations (Unity needs them to register decorators for instance http://bit.ly/XQa9wy), but that's not the case with Simple Injector. The only time I ever saw keyed registrations to make sense in Simple Injector was when a user needed to implement an hybrid lifestyle, but this is fixed in Simple Injector 2.0. That version contains a feature to easily build hybrid lifestyles.
I challenge Martin to come up with an example where keyed registrations are useful (with Simple Injector).
Daniel
1/15/2013
@ChrisW:
I know. But he didn't steal the updates :-)
ChrisW
1/15/2013
Someone stole your blog post !
http://fukyo-it.blogspot.fi/2012/10/ioc-container-benchmark-performance.html
John
1/1/2013
Hi,
please add Caliburn.Micro to list.
Thanks.
Daniel
12/1/2012
@Ken:
Thanks for your hint. The post isn't up to date in all parts.
I will update this within the next days.
Ken
12/1/2012
http://kennethxu.blogspot.com
>> LinFu and Ninject are both much faster than Spring.NET
I didn't get this part. You date clearly indicates that Sprint.Net is much faster than that two. What was wrong? the conclusion or data?
Martin
10/16/2012
Daniel: I just meant adding it to the feature list (not testing it).
Daniel
10/15/2012
@Frantisek:
Thanks for your hint. I updated the code accordingly.
@Martin:
Thanks for your comment. I will update the blog post soon.
I will not add a comparison that tests multiple registrations per type, since not all containers support that feature.
Martin
10/14/2012
Dynamo.IoC is in version 3 now.
I just compared performance against SimpleInjector and it is almost double as fast when it comes to resolving transient instances in my test case.
I think your feature comparison should also include if the container supports multiple registrations for each type (etc. using keys). For an example SimpleInjector does not support this last time I looked at it (as far as i remember).
Frantisek Jandos
10/3/2012
Spring.NET gives much better results, when object is resolved using its name, if SpringContainerAdapter.Resolve() method is rewritten to return (T)container.GetObject(typeof(T).FullName); it will give results ~2x slower for singleton and ~8x slower for transient & combined in comparison to Windsor. I vote for returning it back to the graph as Spring.NET deserves it at least for its excellent documentation in comparison to Windsor :)
Daniel
9/11/2012
@Thoai Nguyen:
Performance is only one criteria among many others. In a desktop application the speed of your container doesn't matter that much. But in a web application things are different. When you handle many requests (using several servers), it makes a difference how much time you waste for setting up your dependencies.
But as I said, it's only one criteria. If your favorite container is fast enough for your needs, just keep using it.
Van Thoai Nguyen
9/11/2012
http://thoai-nguyen.blogspot.com
Thanks for the list.
Is it really a matter of how fast the container is? Who's gonna resolve that much objects in a short time? In my opinion, just choose your favorite container. I used to be happy with Unity, StructureMap and now Autofac is my favorite choice.
Just wonder why people like to invent other libraries. If you can list out the pros and cons of these thing, that would be great.
Cheers.
Jonas Gauffin
8/22/2012
http://blog.gauffin.org
My container (Griffin) now supports interception
Nicholas Blumhardt
8/1/2012
http://nblumhardt.com
Hi Daniel! Interesting to see just how many options we have now :)
Autofac does have custom lifetime support- it is very flexible and is in use today supporting per-thread, per-request, per-transaction, per-message, per-view model and many other scenarios.
We did quite a bit of profiling on the MEF team when creating Microsoft.Composition (http://nuget.org/packages/microsoft.composition) and learnt some interesting things in the process.
First, concurrency makes a HUGE difference to how containers stack up; some scale linearly as CPUs are added, while others actually slow down severely. It would be interesting to see a longer-running concurrent version of these benchmarks.
Second, in real life scenarios using Composition Root, deeper graphs of transient instances appear a lot, e.g. In MVC apps. Performance on deeper graphs is also interesting.
Third, over longer (several minute) runs, the amount of garbage created by the container affects performance. This makes a big difference to throughput that may not show in short runs.
Cheers! Nick
Daniel
5/18/2012
@Dzmitry:
My performance test does not test all features of all containers and and only uses a few types.
If you have configured more types, the results may change.
I never claimed, that my test is perfect for all scenarios! But the various containers show a very different performance even with a few types.
Feel free to create you own test with more complex object graphs.
Last but not least: Performance is not the only criteria that you have to consider when choosing an IOC.
Dzmitry
5/18/2012
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.
Dzmitry
5/18/2012
There are features like Constructor/Property/Method Injection. Unity supports all. May be if turn some off then Unity will be faster (as containers without such features)?
Dzmitry Lahoda
5/18/2012
Do not you think that using small amount of types leads to false results?
Daniel
4/28/2012
@Martin:
I think that the syntax doesn't matter that much.
But if you like it and the performance is good enough for your needs, keep using Ninject.
The dependencies should be configured at a single place (the composition root), so it should be easy to replace Ninject with something else as soon as required.
Martin
4/26/2012
Interesting, it doesn't seem to have affected the performance very much...
I like Ninject's syntax, and it helps that it's the one suggested by Steve Sanderson in the Pro ASP.NET MVC3 book.
Do you have any thoughts on this?
Daniel
4/25/2012
@Martin:
I just updated to the latest versions. Thanks for your hint.
Martin
4/25/2012
I was wondering if you would consider upgrading the versions to the newest ones and re-running.
If not, I'm sure I can try it myself, just thought it might be useful...
Specifically, Ninject 3.0 as I love the syntax, just hoping it's got some comparable performance.
Yours is the most updated blog I've found on this at the moment...
gold price
4/18/2012
http://goldpricetoday.ws
My site is using ninject. May be change to use Dynamo in the near feature. Thanks for your post!
Prakash
3/3/2012
Would been interesting if you add an extra column in your to result that would show flexibility cost or feature count. Then one would be able to see how feature rich the framework is versus performance.
After all its all about balance choosing the right tool for the job.
Prakash
Daniel
2/22/2012
@Tomas:
Thanks for your feedback. I changed the code accordingly. Now I inherit directly from IServiceLocator. Funq and Petite perform much better now.
Tomas Jansson
2/22/2012
http://blog.tomasjansson.com
Interesting comparison, but...
I've downloaded your code and I don't think you give the framework funq a fair comparison. The strength in funq is that it is using generics and therefor doesn't need to use any reflection and everything is already typed. If you look at munq, which I think is a fork of funq, it has really impressive numbers and funq should have approximately the same. Also, I changed your implementation and inherited directly from IServiceLocator instead of ServiceLocatorImpl and got numbers that are far from you result.
So please, when you do a benchmark do it the way that shows of the strength of all the frameworks.
Will
2/9/2012
http://www.storm-studios.net
Not sure why xml configuration is a detriment. I hear developers complain about that and I just scratch my head. Oh, well, Spring.NET with all of it's useful facilities works for me.
Daniel
2/1/2012
@Marijn:
I don't know why Spring is that slow.
I'm only testing service location, since all other features like interception are not supported by all containers.
Marijn
2/1/2012
Interesting read. Any thought on why you think Spring.NET is so slow? Maybe you could update your post to clarify that your test is only testing ServiceLocator style usage of the container.
tibel
1/21/2012
Please check also:
https://github.com/grumpydev/TinyIoC
http://microioc.codeplex.com/
Another interesting point would be, if the IoC container will also work on silverlight, compact framework or WP7...
Pranav Shah
12/16/2011
Would you consider adding two more to the list:
http://www.dynamoioc.com/
http://www.dynamoioc.com/
I came across them while reading another article:
http://blog.opennetcf.com/ctacke/2011/04/29/BenchmarkingOpenNETCFsIoCFramework.aspx
Daniel
11/3/2011
@Ady:
I added the version information
Ady
11/3/2011
Could you state the version of each IOC that you have compared ?
Daniel
9/13/2011
@Andrew:
Thanks for your hint. I have added Funq and Munq to the comparison. PicoContainer is a Java container and Seasar is not very easy to use, so I did not add these frameworks.
Funq and Munq are really fast.
Andrew
9/12/2011
Would you like to include some other less prominent IoCs in the comparison?
Funq http://funq.codeplex.com/
Munq http://munq.codeplex.com/
S2Container.NET http://s2container.net.seasar.org/en/index.html
PicoContainer http://docs.codehaus.org/display/PICO/Home