A few months ago I ran across a blog post about getting started with Dapper.NET. I had heard of Dapper before but had never actually tried to use it. Dapper is known for being fast, but I was curious just how much faster it would be in the situations I typically find myself: writing database queries. I’ve long used Entity Framework for data layers, which is often criticized for being slow.

To test out Dapper’s speed, I built four basic tests so I could compare its performance to Entity Framework. If you’d like to run these experiments yourself, all the code used for this blog post is available on GitHub.

Data Model

The data model is relatively small and simple. I’ve worked on a few projects involving athletes so that was my starting point.

[sourcecode language=”plain”]

public class Athlete
{
public long Id { get; set;}

public string FirstName { get; set; }

public string LastName { get; set; }

public string Position { get; set; }
}

[/sourcecode]

An athlete is nothing without a team, which leads to the next class.

[sourcecode language=”plain”]
public class Team
{
public long Id { get; set; }

public string Name { get; set; }
}

[/sourcecode]

An athlete can, of course, be on multiple teams so a third class is needed to link the two.

[sourcecode language=”plain”]
public class AthleteTeam
{
public long AthleteId { get; set; }

public long TeamId { get; set; }
}
[/sourcecode]

I’ve never had a good experience when using Entity Framework to manage the relationships between objects, so there are no navigation properties on these objects. They are a straight mapping of class to database table. I mostly use ORMs to reduce the amount of SQL I write, not necessarily to manage the relationships between my objects.

Test Setup

Before starting any tests, I seeded my database with three sports teams with each containing 1,000 athletes. The first thing I found was both Entity Framework and Dapper take longer with the first query than with subsequent queries. For Entity Framework, I know a query has to be complied on the first execution, but for Dapper I’m not sure what it’s doing during the first execution. For all tests, I ran each query twice and ran each test 10 times before averaging out the results. All times are in milliseconds.

Loading 1 Athlete

In the first test, I loaded a single athlete by Id from the database.

Test IterationEntity Framework FirstEntity Framework SecondDapper FirstDapper Second
134813836
236115815
333213676
431211676
531314696
633414696
736812757
833113729
933313726
1032114698
Average (ms)335.313.172.66.7

There’s no denying that Dapper is faster than Entity Framework, especially on the first execution. Compiling the LINQ query is an expensive event.

Loading Many Athletes by Position

In the second test, I loaded all the athletes for a specific position to see how each framework fared loading multiple records and searching on a string field instead of a primary key.

Test IterationEntity Framework FirstEntity Framework SecondDapper FirstDapper Second
18035137
283331910
38133128
47533117
56933117
67933117
77838127
87232128
97632128
106534146
Average (ms)75.833.812.77.5

The differences between the first and second queries were less extreme for the second test. My suspicion is both frameworks are mapping the database on the first query and pay an extra time penalty. Loading more results also increased the gap in speed between the second Entity Framework and Dapper queries.

Loading Teams with Athletes

I wanted to see how well each framework would handle joins which led to the third test: loading a team with all 1,000 athletes.

Test IterationEntity Framework FirstEntity Framework SecondDapper FirstDapper Second
1143382316
2144422720
3127392116
4132292126
5136382822
6142372420
7132352216
8133392216
9127362418
10121372121
Average (ms)133.73723.319.1

The results are pretty consistent with the other tests. Entity Framework is still lagging behind, but there was a Dapper run that took longer on the second query rather than the first. On average though the second Dapper query still ran 4.2 milliseconds faster.

Inserting Athletes

In the last test, I wanted to look at the speed differences inserting records into the database. I inserted one athlete at a time and for Dapper I used the Dapper-Extensions nuget package to handle the insert. The package reduces an insert to a single method call. In the past, the insert code I’ve seen has always looked a little weird and was one of my main complaints about Dapper.

Test IterationEntity Framework FirstEntity Framework SecondDapper FirstDapper Second
128414856
227811917
325212835
4249111066
526810767
626810808
726612926
826713868
925611807
1025311786
Average (ms)264.111.585.76.6

Surprisingly, the first Dapper queries took around as long as the first queries for loading a single athlete. I don’t know enough about the internals of the Dapper-Extensions, but it seems likely there is an additional step taken when using its insert functionality. Otherwise the results are consistent with the trends seen across the other tests.

Conclusion

Dapper was written with speed as a priority and the tests definitely prove this out. However, if we ignore the overhead of the first query, the difference between the two ranged from 5-25 milliseconds. The largest site I know of using Dapper is Stack Overflow and I would think they definitely benefit from saving milliseconds anywhere they can. In a smaller application I’m not sure it makes sense to make an ORM decision solely for the sake of a few milliseconds. Instead I would pick based on the style of the code written for either framework. I like Entity Framework for its LINQ integration and will continue to favor it for that. To me using Dapper felt like writing SQL, which I try to avoid when possible.

In the past when a query starts to take too long executing through Entity Framework I have replaced it with either a view or a stored procedure, depending on the situation. Going forward, Dapper will be a valuable tool that could be used before going straight to raw SQL.

Looking For More?

Sign up to receive useful software development tips and news from the Don't Panic Labs team.

You have successfully subscribed!

Share This