I was doing some benchmarking on various ORMs to see how our own ORM framework's performance relates to that. The topic of this benchmark is solely entity object materialization, so a large set is fetched and materialized into entity objects. I use AdventureWorks
for this, on SQL Server 2005 (not really important, see below). I fetch all 31465 rows of Sales.SalesOrderHeader. I run all benchmarks on a core2quad with windows 8, 32bit, 4GB ram, .NET 4.5.1 installed (VS.NET 2012/2013) and all are release builds.
The results with EFv5 (with code) are here:
This morning I changed EFv5 code for EFv6 (6.0.1, latest from nuget) and reran the benchmarks. I was surprised to see that EFv6 was 3 times slower. See:
. I checked whether it re-imported the EDMX every time which wasn't the case, creating the context is once 136ms or so, the other times 0ms.
I ran a profile on the DB activity using our profiler to see whether I configured something wrong. EFv6 executes 1 query per loop, which is expected, spends 2.34ms on the SQL query execution, and roughly between 536-650ms on consuming the 31K rows from the
datareader. So on that side, things are all OK.
So I ran a .NET profile with dotTrace 4.5.1, and things look seriously wrong. See screenshot:
I've saved this snapshot, in case you want to look at it.
As this was run with EFv6 code generated with our designer, I wondered whether I made a mistake somewhere, configured it wrong, so I created an AdventureWorks project using the VS.NET 2013 designer for EFv6. Imported all tables, accepted all defaults and generated
code using the shipped .tt. Updated the references to 6.0.1 from nuget and basically did the same benchmark again. Release builds, .NET 4.5. To my surprise it was even slower:
Fetched 31465 entity framework v6.0.1 entities from the DB. Took 9837ms
Fetched 31465 entity framework v6.0.1 entities from the DB. Took 7767ms
Fetched 31465 entity framework v6.0.1 entities from the DB. Took 7724ms
Fetched 31465 entity framework v6.0.1 entities from the DB. Took 7508ms
Absurd slowness compared to EFv5, so I again ran a .NET profiling using dotTrace. It spends 0.02% of its time in the GetEnumerator to fetch the actual data, and the rest in the MoveNext over the result. I've also saved this snapshot, in case you want to look
at it. (it's 14MB so I can't attach it).
I've attached this second code base, it's simple code generated from the MS designer.
To me something is seriously off, however I have no idea what. From the looks of it, EF tries to do a lot of stuff with the data pulled from the DB which is irrelevant (as it's a single set of entities, no FKs, related entities, inheritance etc.).
Hope this helps, let me know if you want the dotTrace (a product from JetBrains) snapshots or that I have to run something else for you.
Frans Bouma, lead dev LLBLGen Pro.