Choosing Between EF Core and Dapper — Benchmarking Performance and Efficiency

When working with .NET applications, developers often face a choice between Entity Framework Core (EF Core) and Dapper for data access. EF Core is a full-fledged ORM that offers a rich set of features like migrations, LINQ queries, and change tracking, making it a convenient option for applications with complex data relationships. Dapper, on the other hand, is a lightweight ORM known for its performance, with minimal overhead and direct mapping capabilities.

The question then arises: When does it make sense to choose EF Core over Dapper, and vice versa? In this article, we’ll benchmark both ORMs to compare their performance and memory usage across common operations, providing insights on when each might be the better choice.

To get accurate results, I used BenchmarkDotNet, a popular .NET library designed for performance testing, which provides consistent measurements of execution time and memory allocation. Here’s a quick look at the environment and setup used for this benchmark:

For this test, I inserted 1 million records into a table of product data using the Bogus library to generate realistic sample data. I then benchmarked three types of operations using EF Core and Dapper:

Retrieving by ID:

Inserting a Product:

Finding products with Filters like minimum price of 75 and maximum price of 1000 sorted by price in descending order with pagination of 50 records per page:

For further details, the full code is available on GitHub.

To provide a thorough analysis, I ran two sets of benchmarks for each operation: a single operation and 50 consecutive operations. Let’s break down the results by operation type:

1. Retrieving by ID

For a single operation:

MethodMeanErrorStdDevAllocated
GetByIdWithDapperAsync104.2 us2.06 us4.73 us7.55 KB
GetByIdWithEFCoreAsync240.6 us4.76 us8.94 us104.44 KB
GetByIdWithEFCoreAsNoTrackingAsync250.2 us2.07 us1.93 us103.96 KB

For 50 consecutive operations:

MethodMeanErrorStdDevAllocated
GetByIdWithDapperAsync5.086 ms0.1073 ms0.3061 ms366.99 KB
GetByIdWithEFCoreAsync13.975 ms0.2430 ms0.3406 ms5206.96 KB
GetByIdWithEFCoreAsNoTrackingAsync13.578 ms0.1481 ms0.1312 ms5177.34 KB

Summary:

2. Finding Products with Filters, Sorting, and Pagination

For a single operation:

MethodMeanErrorStdDevAllocated
FindWithFilterOrderByPaginationWithDapperAsync620,303.9 us10,092.80 us9,440.81 us42.02 KB
FindWithFilterOrderByPaginationWithEFCoreAsync636,583.7 us12,314.05 us11,518.57 us256.57 KB
FindWithFilterOrderByPaginationWithEFCoreAsNoTrackingAsync620,287.4 us7,573.23 us7,084.01 us223.68 KB

For 50 consecutive operations:

MethodMeanErrorStdDevAllocated
FindWithFilterOrderByPaginationWithDapperAsync43,612.958 ms474.2633 ms443.6262 ms2048.23 KB
FindWithFilterOrderByPaginationWithEFCoreAsync37,708.436 ms140.6169 ms109.7844 ms9988.21 KB
FindWithFilterOrderByPaginationWithEFCoreAsNoTrackingAsync37,770.107 ms214.9115 ms179.4608 ms8326.77 KB

Summary:

3. Inserting a Product

For a single operation:

MethodMeanErrorStdDevAllocated
InsertProductWithDapperAsync167.3 us3.15 us4.10 us6.83 KB
InsertProductWithEFCoreAsync367.8 us7.24 us16.48 us110.8 KB

For 50 consecutive operations:

MethodMeanErrorStdDevAllocated
InsertProductWithDapperAsync9.218 ms0.1760 ms0.1560 ms333.41 KB
InsertProductWithEFCoreAsync18.945 ms0.2834 ms0.2512 ms5530.56 KB

Summary:

Overall Insights

In summary, each ORM has distinct strengths, making them suitable for different use cases in application development.

Dapper:

EF Core:

Conclusion

For high-performance cases needing rapid execution and low memory use, Dapper is ideal. EF Core, however, is better for complex data handling and change tracking. Evaluating each ORM on a case-by-case basis is wise, especially for operations where consistent performance is critical. A practical approach could be to start with EF Core for command-type operations, especially when working with complex entity models that need change tracking. Meanwhile, consider using Dapper for read operations to leverage its speed and the flexibility of SQL, delivering data efficiently to end users.

Reference