Entity Framework dramatically faster in .NET 4.5

The Entity Framework is often shown lagging behind in performance comparisons with other ORM’s, especially when micro ORM’s are also included in the mix.

For example the Dapper benchmarks show the Entity Framework in a distant last place when testing SELECT mapping and serialization. These results have been charted on the excellent ServiceStack website.

However things have changed in .net 4.5 and the Entity Framework is no longer the slouch it once was.

The chart below shows the same benchmark, but this time including how the ORM’s fare when run on .NET 4.5.

The benchmark measures how long in milliseconds it takes to execute 500 SELECT statements against a DB and map the data returned to objects.

[easychart type=”vertbar” height=”100″ title=”Performance of SELECT mapping over 500 iterations” groupnames=”.NET 4.5, .NET 4″ groupcolors=”005599,229944″ valuenames=”Hand coded, Dapper,OrmLite,PetaPoco,NHibernate,EF Compiled ,EF, Linq 2 SQL,NHib LINQ” group1values=”66,67,71,75,126,133,183,188,530″ group2values=”68,69,80,78,134,133,888,212,657″]

Now the Entity Framework competes with the other ORM’s on performance, and when compared with a fully featured ORM like nHibernate it compares very favourably (at least on this one metric).

It gets nowhere near the micro-ORM’s on performance, but feature rich ORM’s never will.

What is also interesting is that quite a few of the ORM’s also gain speed improvements in .NET 4.5

12 thoughts on “Entity Framework dramatically faster in .NET 4.5”

  1. One reason the new version is faster is that EF now automatically pseudo-compiles expressions and caches an intermediate version of the expression which saves a lot of time. If the test repeats the same expression, you’ll see a big difference (unless you were already using “EF Compiled” queries).

    It would have been nice if EF cached the actual compiled delegate or at least made it available for implementers to cache and manage. The delegate is even faster and it would save programmers from having to declare lambdas to get compiled query speed.

  2. Do you know why this is? I wonder – is it specific optimisations within the .NET 4.5 runtime that EF can now use, or is it that EF has been significantly revamped? Would be really curious to know as the solution may help in other more general object mapping/instantiation code.

  3. Dave/Clint – I think there was a small difference when I ran a benchmark to compare but it was minimal. I will follow up with another post, once I am sure I have got it correct.

    Erik – Agree with you on this, it is not very convenient or pretty to have to compile all the queries. Maybe EF6 will improve things.

    JB – I believe Erik has hit the nail on the head. The performance improvements are specific to EF5 and .net 4.5 in combination. You don’t get the improvements in the latest EF if you are still on .net 4.

  4. After some more thinking, if the worst performing ORM can perform 500 operations in 800ms, I’m going to base my ORM choice on other features.

    Still, this looks like a fantastic improvement.

  5. I wish you would’ve tested BLToolkit as well. We get close to Dapper performance but still use LINQ (i.e. no magic strings). BLToolkit is about 3-4 times faster than Linq2Sql in the projects we worked with. And if you go through the effort of compiling BLToolkit LINQ queries you can get withing 10% of Dapper — pretty impressive imo. For a highly used page we went from a render time of 200ms to 60ms by simply swapping out Linq2Sql with BLToolkit.

  6. I’m maintaining the caching provider for Entity Framework, do you want to test the perfomances using it?
    It’s on http://nuget.org/packages/EyeSoft.Data.EntityFramework.Caching. To enable the cache just write Database.DefaultConnectionFactory = new CachedContextConnectionFactory(); in the application start section. Is possible to use any distributed cache (Couchbase, AppFabric…) implementing the ICache interface and pass it to the CachedContextConnectionFactory.

  7. These numbers are, sorry, bullshit. When you look at actual benchmark code which uses a model with more than 1 entity, https://github.com/FransBouma/RawDataAccessBencher, you’ll see EF v6 is only fast when you fetch readonly, non-change tracked entities. When you fetch normal entities, be it a set or just 1 entity (which are also in the benchmark) over and over, the fetch performance of EFv6 is slow. This is due to the fact that it contains a serious performance bottleneck, described here: https://entityframework.codeplex.com/workitem/1829 So, claiming EFv6 is now very fast is, sorry, unfounded, as all evidence suggests otherwise.

Leave a Reply

Your email address will not be published. Required fields are marked *