Daniel Palme

Daniel Palme

.NET consultant from Germany.

Blog > IoC Container Benchmark - Performance comparison

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, then not all containers are suited. But if the container is "only" used for wiring up dependencies, why not choose the fastest one?

The test setup

The contestants

You probably have heard of most of the frameworks, but one of them is quite new and works differently: Hiro
The author, Philip Laureano, names it an "inversion of control container compiler framework". After configuration, the container gets compiled and is immutable from now on. This concept makes this container really fast.

The test setup

To test the performance I register three interfaces and their corresponding implementation to every container.
The first one is registered as a singleton, the second one as transient (a new instance is created every time). The third also has a transient lifetime, but moreover has a dependency to the first two interfaces (which get injected by constructor injection).

Every interface is resolved 1.000.000 times and the time is measured in milliseconds.

The results

Overview

ContainerSingletonTransientCombinedComplexPropertyGenericsIEnumerableConditionalChild ContainerInterception
No11594102127124982668669079
Autofac 3.3.182621325659161123466848821736011025045333
Caliburn.Micro 1.5.24745661664740296707156
Catel 3.9.037244981335033606126974384
DryIoc 1.2.05377821011316935466
Dynamo 3.0.2.0108140216791913
fFastInjector 0.8.198129164271
Funq 1.0.0.015818642312711211
Grace 2.2.1181223578177818635032790670129608102
Griffin 1.1.12692617092026
HaveBox 2.0.078869515110252177883
Hiro 1.0.4.417951961952082633013
IfInjector 0.8.199152175231422167
LightCore 1.5.119030003650321589824742505552115
LightInject 3.0.1.651717412111587355651568
LinFu 2.3.0.4155940672646766663184134
Maestro 1.3.1427519145958879301277980242355282481009538
Mef 4.0.0.0330625043380331156652165820186915117780
Mef2 1.0.20.032230136459614743121657
MicroSliver 2.1.6.025278727817985
Mugen 3.5.14828362283846114046702326643180567698017034
Munq 3.1.610814350218621648
Ninject 3.2.0.08970203144735513015611451051063102846733571983110031037
Petite 0.3.255844980561261296995
SimpleInjector 2.5.08510912316922710985322863013380
Spring.NET 1.3.21063167944473611456510465275437
StructureMap 2.6.4.1169420105970205312121568812194977510011402
StyleMVVM 3.1.553557485416961792291438282830
TinyIoC 1.240025551021545779434616900
Unity 3.0.1304.1332151712106853036531427408746320133957
Windsor 3.2.150826038161232084737843302286331755022180

Singleton

IocPerformance - Singleton

Transient

IocPerformance - Transient

Combined

IocPerformance - Combined

Feature comparison

Performance Configuration Features Environment
Container Code XML Auto Autowiring Custom lifetimes Interception .NET SL WP7 WinRT
AutoFac Average Yes Yes Yes Yes No Yes Yes Yes YesYes
Caliburn.Micro Average No No No Yes No No Yes Yes YesYes
Catel Average Yes Yes No Yes Yes Yes Yes Yes YesYes
DryIoc Fast Yes No No Yes Yes No Yes No NoNo
Dynamo Fast Yes No Yes Yes Yes No Yes No NoNo
fFastInjector Fast Yes No No Yes No No Yes Yes YesYes
Funq Fast Yes No No No No No YesYes YesYes
Grace Average Yes Yes Yes Yes Yes Yes Yes No NoYes
Griffin Fast Yes No No Yes No Yes Yes No NoNo
HaveBox Fast Yes No No Yes No Yes Yes No NoNo
Hiro Fast Yes No No Yes No No Yes No NoNo
IfInjector Fast Yes No No Yes No No Yes Yes YesYes
LightCore Average Yes Yes Yes Yes Yes No Yes Yes NoNo
LightInject Fast Yes No Yes Yes Yes Yes Yes Yes NoYes
LinFu Slow Yes No No Yes No Yes Yes No NoNo
Maestro Average Yes No No Yes Yes Yes Yes Yes YesYes
MEF Slow Yes No No Yes No No Yes Yes NoYes
MEF2 Fast Yes No No Yes No No Yes No YesYes
MicroSliver Average Yes No No Yes No No Yes Yes NoYes
Mugen Average Yes No No Yes Yes Yes Yes Yes YesYes
Munq Fast Yes No No Yes Yes No Yes No YesNo
Ninject Slow Yes Yes Yes Yes Yes No Yes Yes YesYes
Petite Fast Yes No No No No No Yes No NoNo
SimpleInjector Fast Yes No Yes Yes Yes Yes Yes Yes NoNo
Speedioc Fast Yes No No No No No Yes No NoNo
Spring.NET Very slow No Yes No Yes No Yes Yes No NoNo
Stiletto Average Yes No No Yes No No Yes Yes YesNo
StructureMap Average Yes Yes Yes Yes Yes Yes Yes No YesNo
StyleMVVM Fast Yes No Yes Yes Yes No Yes No NoYes
TinyIoc Average Yes No No Yes Yes No Yes Yes YesNo
Unity Average Yes Yes Yes Yes Yes Yes Yes Yes NoYes
Windsor Average Yes Yes Yes Yes Yes Yes Yes Yes NoNo

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.

SimpleInjector, Hiro, Funq, Munq and Dynamo offer the best performance, they are extremely fast. Give them a try!
Especially Simple Injector seems to be a good choice. It's very fast, has a good documentation and also supports advanced scenarios like interception and generic decorators.

Updates

13.09.2011: Funq and Munq have been added to the list of contestants, both frameworks are really fast. The updated charts do no more contain Spring.NET, since it was extremly slow.

04.11.2011: I added Simple Injector, the performance is the best of all contestants.

16.12.2011: I added Dynamo.Ioc, the performance is very close to Simple Injector and Hiro.

22.01.2012: Added TinyIoc.

22.02.2012: Updated IServiceLocator implementations.

12.03.2012: Added LightInject. Added feature comparison.

25.04.2012: Updated to Ninject 3.0.015 and Petite 0.3.2.

14.05.2012: Added Mugen.

14.06.2012: Added MEF.

18.06.2012: Added Griffin.

20.08.2012: Updated to Castle Windsor 3.1.0, LightInject 2.0.0.0, Simple Injector 1.5.0.12199, Structuremap 2.6.4.1, MugenInjection 2.6.0 and Unity 2.1.505.2

18.09.2012: Added Catel.

15.10.2012: Updated to Dynamo.Ioc 3.0.1.0 and MugenInjection 3.0.0

15.12.2012: Updated to Catel 3.4, Griffin.Container 1.1.0, SimpleInjector 1.6.0.12319, TinyIoC 1.2

01.01.2013: Added Caliburn.Micro 1.4

06.01.2013: Added Speedioc. Updated to Autofac 3.0.0, Caliburn.Micro.Container 1.4.1, LightCore 1.5.0

26.02.2013: Updated to Autofac 3.0.1, LightCore 1.5.1, Windsor 3.2.0

15.03.2013: Added benchmark for interception

03.04.2013: Added MicroSliver

11.04.2013: Updated several containers

09.05.2013: Updated LightInject, SimpleInjector and Unity

02.06.2013: Added fFastInjector and HaveBox. Updated Dynamo.IOC

16.06.2013: Updated HaveBox.

16.06.2013: Added StyleMVVM.

04.07.2013: Ian Johnson contributed some more advanced tests. Interesting to see how slow some containers are, when the object graph gets a little bigger.

26.07.2013: Added IfFastInjector.

03.08.2013: Added Stiletto.

03.09.2013: Updated several containers. Ignored Stiletto since it uses Fody, which makes some problems.

17.11.2013: Added Grace. Updated several containers.

15.12.2013: Added Maestro. Updated several containers.

11.02.2014: Added MEF2.

10.04.2014: Updated benchmark. Updated several containers.

Source code

Latest source code is available on Github.

Downloads

IocPerformance.7z


Subscribe to RSS Feed

Tags: .NET, C#
 

Related posts

 

New comment

:

:

:

:

 

Comments

#1
Andrew

Andrew

09/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
 
#2
Daniel

Daniel

09/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.
 
#3
Ady

Ady

11/03/2011

Could you state the version of each IOC that you have compared ?
 
#4
Daniel

Daniel

11/03/2011

@Ady:
I added the version information
 
#5
Pranav Shah

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
 
#6
tibel

tibel

01/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...
 
#7
Marijn

Marijn

02/01/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.
 
#8
Daniel

Daniel

02/01/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.
 
#9
Will

Will

02/09/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.
 
#10
Tomas Jansson

Tomas Jansson

02/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.
 
#11
Daniel

Daniel

02/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.
 
#12
Prakash

Prakash

03/03/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
 
#13
gold price

gold price

04/18/2012 | http://goldpricetoday.ws

My site is using ninject. May be change to use Dynamo in the near feature. Thanks for your post!
 
#14
Martin

Martin

04/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...
 
#15
Daniel

Daniel

04/25/2012

@Martin:
I just updated to the latest versions. Thanks for your hint.
 
#16
Martin

Martin

04/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?
 
#17
Daniel

Daniel

04/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.
 
#18
Dzmitry Lahoda

Dzmitry Lahoda

05/18/2012

Do not you think that using small amount of types leads to false results?
 
#19
Dzmitry

Dzmitry

05/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)?
 
#20
Dzmitry

Dzmitry

05/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.
 
#21
Daniel

Daniel

05/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.
 
#22
Nicholas Blumhardt

Nicholas Blumhardt

08/01/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
 
#23
Jonas Gauffin

Jonas Gauffin

08/22/2012 | http://blog.gauffin.org

My container (Griffin) now supports interception
 
#24
Van Thoai Nguyen

Van Thoai Nguyen

09/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.
 
#25
Daniel

Daniel

09/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.
 
#26
Frantisek Jandos

Frantisek Jandos

10/03/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 :)
 
#27
Martin

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).
 
#28
Daniel

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.
 
#29
Martin

Martin

10/16/2012

Daniel: I just meant adding it to the feature list (not testing it).
 
#30
Ken

Ken

12/01/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?
 
#31
Daniel

Daniel

12/01/2012

@Ken:
Thanks for your hint. The post isn't up to date in all parts.
I will update this within the next days.
 
#32
John

John

01/01/2013

Hi,

please add Caliburn.Micro to list.

Thanks.
 
#33
ChrisW

ChrisW

01/15/2013

Someone stole your blog post !

http://fukyo-it.blogspot.fi/2012/10/ioc-container-benchmark-performance.html
 
#34
Daniel

Daniel

01/15/2013

@ChrisW:
I know. But he didn't steal the updates :-)
 
#35
Steven

Steven

02/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).
 
#36
Tim

Tim

02/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
 
#37
AceHack

AceHack

03/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
 
#38
Daniel

Daniel

03/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.
 
#39
AceHack

AceHack

03/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.
 
#40
AceHack

AceHack

03/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.
 
#41
Daniel

Daniel

03/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.
 
#42
Steve

Steve

03/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.

 
#43
Daniel

Daniel

03/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.
 
#44
David Walker

David Walker

06/01/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/
 
#45
Christian Henrik Reich

Christian Henrik Reich

06/02/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
 
#46
Karim

Karim

06/03/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.
 
#47
dadhi

dadhi

06/04/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.
 
#48
Be aware

Be aware

06/04/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. :)
 
#49
Christian Henrik Reich

Christian Henrik Reich

06/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
 
#50
Christian Henrik Reich

Christian Henrik Reich

06/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
 
#51
Ian Johnson

Ian Johnson

06/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
 
#52
Nikhil Pinto

Nikhil Pinto

06/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.
 
#53
Daniel

Daniel

06/18/2013

@Nikhil:
There is an extension for Ninject:
https://github.com/ninject/ninject.extensions.interception
 
#54
Christian Henrik Reich

Christian Henrik Reich

06/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
 
#55
David Walker

David Walker

07/02/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.
 
#56
Christian Henrik Reich

Christian Henrik Reich

07/04/2013 | http://www.havebox.net

Good Work, Ian Johnsen :-)
 
#57
Jury Soldatenkov

Jury Soldatenkov

07/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.
 
#58
Christian Henrik Reich

Christian Henrik Reich

07/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
 
#59
Christian Henrik Reich

Christian Henrik Reich

07/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
 
#60
Ian Johnson

Ian Johnson

07/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
 
#61
Jury Soldatenkov

Jury Soldatenkov

07/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.
 
#62
Christian Henrik Reich

Christian Henrik Reich

07/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
 
#63
Mike

Mike

07/26/2013 | https://github.com/iamahern/IfFastInjector

@Danial: Thanks for getting IfFastInjector up there so quickly!
 
#64
Christian Henrik Reich

Christian Henrik Reich

07/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

 
#65
Christian Henrik Reich

Christian Henrik Reich

08/01/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
 
#66
Mike

Mike

08/03/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
 
#67
Christian Henrik Reich

Christian Henrik Reich

08/05/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
 
#68
Daniel

Daniel

09/01/2013

Ninject supports both interception and Xml config via extensions.
 
#69
Brent Roady

Brent Roady

09/03/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!
 
#70
Rajiv Mounguengue

Rajiv Mounguengue

09/06/2013

Hi Daniel, Catel supports Interception now.
 
#71
Thomas

Thomas

10/24/2013

Great Work! Helped me a lot to decide witch IoC to use in projects!
 
#72
ashley wardell

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

 
#73
Daniel

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 :-)
 
#74
Ian Johnson

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
 
#75
Ivan

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)
 
#76
Valy

Valy

01/05/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.
 
#77
dadhi

dadhi

01/08/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.
 
#78
Ian Johnson

Ian Johnson

01/08/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
 
#79
dadhi

dadhi

01/09/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.
 
#80
Ian Johnson

Ian Johnson

01/09/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?
 
#81
dadhi

dadhi

01/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.
 
#82
Mike

Mike

01/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
 
#83
dadhi

dadhi

01/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.
 
#84
JP

JP

03/06/2014

Which of these is the easiest to learn & implement?
 
#85
Mike

Mike

03/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.
 

Pingbacks

http://www.pearltrees.com/nickcamporillo/inversion-control/id4594800#pearl38464929&show=reveal,6