Performance Comparison of Entity Framework Core 2.1 and Dapper 1.5
tl;dr - ignore most (maybe all) of the posts out there comparing Dapper and Entity Framework performance, you need to measure it yourself.
Here’s why -
- Some are angry opinion pieces from people who don’t like one technology or the other and clearly haven’t run any tests.
- All are out of date (as this one will be shortly) because the libraries move so quickly.
- None are running against the database and network you have.
- Your standard queries are far more important than whatever arbitrary queries they used.
I recently had to decide between a few different ORMs for a project, the specifics of the project are irrelevant, but I was using a Postgres database that had lots of data (my lots and your lots are probably different, that I had hundreds of millions of records should not matter to you).
Most of the posts comparing Dapper and EF that I read came down on the side of Dapper, some by a tiny margin and one by no margin but a lot of bluster.
Rather than trust any of these posts I wrote my own benchmarking application using the BenchmarkDotNet library.
I picked seven of the most representative queries I was making and coded them up in both Dapper and EF. Some of the queries pulled back tens of thousands of records and some brought back scores of records, but the most important thing was that these were queries I was going to run in the finished application.
BenchmarkDotNet takes care of things making sure the code has been jitted, that everything has been “warmed up” and then it runs the same request repeatedly to get a useful average.
On top of this, I ran the whole suite of benchmarking tests multiple time, at different times of the day because my application does not live in a vacuum, I needed to know how it would react when the network or database is under more or less load.
At the end of all this Entity Framework came out on top; for the vast majority of test runs it performed better.
Here are the results of one of the test runs, I didn’t pick the best or the worst, but this one is is indicative of what I saw for the majority of tests.
|EF_Query1||431.19 ms||13.9615 ms||38.1581 ms||445.98 ms|
|Dapper_Query1||689.88 ms||35.9716 ms||102.7689 ms||668.13 ms|
|EF_Query2||45.21 ms||1.5613 ms||4.6816 ms||46.35 ms|
|Dapper_Query2||61.55 ms||1.7915 ms||5.0850 ms||62.19 ms|
|EF_Query3||278.72 ms||51.4681 ms||150.8833 ms||351.38 ms|
|Dapper_Query3||298.64 ms||7.3619 ms||20.2561 ms||297.15 ms|
|EF_Query4||17.97 ms||0.3570 ms||0.6310 ms||17.93 ms|
|Dapper_Query4||26.59 ms||0.6516 ms||1.7592 ms||25.78 ms|
|EF_Query5||70.78 ms||1.4936 ms||4.0985 ms||71.21 ms|
|Dapper_Query5||116.71 ms||2.5632 ms||7.4015 ms||116.36 ms|
|EF_Query6||189.71 ms||50.1289 ms||148.7825 ms||311.21 ms|
|Dapper_Query6||248.61 ms||7.2891 ms||21.1751 ms||304.16 ms|
|EF_Query7||266.62 ms||6.2219||20.3179 ms||281.27 ms|
|Dapper_Query7||304.27 ms||7.8163 ms||15.1561 ms||301.21 ms|
I was a little surprised at this result, but there you have it. EF Core 2.1 is better for me than Dapper.
Out of interest, I took a small portion of my data and put it into SqlServer, and re-ran the tests. This time, Dapper came out slightly ahead. But the SqlServer is on a different network than the Postgres db, is under different load and had a much small dataset so not a realistic exercise.
The moral of the story is you have to test performance yourself, there is absolutely no way you can extrapolate from a test someone wrote about in a blog (including this one) when judging how an ORM will perform for you.