# .NET's ORM Performance Test
# Why
- You can always hear an ORM performance higher than Dapper.
- You should have the following questions:
- Whether the benchmark is authoritative or not
- Is the method of benchmarking reasonable?
- Whether the benchmark's criteria can be harmonized
- Uniform benchmarking standards/norms
# How to perform the correct performance test
Believe that there is no doubt about Dapper's performance and the authority of the benchmark (otherwise there won't be so many ORMs that directly select Dapper when performing performance tests), so we'll use the Dapper Performance Benchmark (https://github.com/StackExchange/Dapper) as our benchmark template and add some ORM that is not included in the benchmark. Thus, there is generally a standard and safeguard from rationality/credibility.
Next up is the Fork Dapper GitHub warehouse, and adds SmartSql (https://github.com/dotnetcore/SmartSql)/IBatis.net and so on.
Source address:https://github.com/Ahoo-Wang/Dapper (opens new window),Please submit the test method to me if you have questions about the test results.
# How to do the above benchmark on your own
Readers are strongly advised to run the benchmark themselves by following these steps.
- Git-Clone https://github.com/Ahoo-Wang/Dapper (opens new window)
- cd Dapper/Dapper.Tests.Performance
- dotnet publish -c release
- run Dapper.Tests.Performance.exe
- Prompt for input, please enter the "*" to run all the benchmarks
- Waiting for test results, directory:BenchmarkDotNet.Artifacts ,There will be a log file, and results folder (test results files are stored in this directory)
# Benchmark results
Important: FreeSql/SqlSugar Official nuget package is a non-Release version, so test results are affected for reference only.
BenchmarkDotNet=v0.11.1, OS=Windows 10.0.17763
Intel Core i7-8750H CPU 2.20GHz (Max: 2.21GHz) (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
[Host] : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.8.3801.0
ShortRun : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.8.3801.0
ORM | Method | Return | Mean | Rank | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|
Belgrade | ExecuteReader | Post | 78.74 us | 1 | 2.2500 | 0.6250 | - | 10.63 KB |
LINQ to DB | 'First (Compiled)' | Post | 97.61 us | 2 | 0.5000 | - | - | 2.67 KB |
LINQ to DB | Query<T> | Post | 103.05 us | 3 | 1.3750 | 0.1250 | - | 6.91 KB |
Hand Coded | SqlCommand | Post | 107.37 us | 4 | 2.0000 | 1.0000 | 0.5000 | 12.29 KB |
Dapper | QueryFirstOrDefault<dynamic> | dynamic | 110.83 us | 5 | 2.8750 | 0.1250 | - | 13.57 KB |
Dapper | QueryFirstOrDefault<T> | Post | 111.65 us | 5 | 2.2500 | 1.0000 | 0.3750 | 13.53 KB |
Hand Coded | DataTable | dynamic | 114.78 us | 6 | 2.0000 | 0.5000 | - | 12.51 KB |
PetaPoco | 'Fetch<T> (Fast)' | Post | 114.95 us | 6 | 2.2500 | 0.8750 | 0.2500 | 13.71 KB |
Dapper | 'Query<dynamic> (buffered)' | dynamic | 115.54 us | 6 | 2.2500 | 1.0000 | 0.2500 | 13.93 KB |
PetaPoco | Fetch<T> | Post | 119.76 us | 7 | 2.5000 | 1.0000 | 0.2500 | 14.66 KB |
Dapper | 'Query<T> (buffered)' | Post | 122.10 us | 8 | 2.2500 | 0.8750 | 0.3750 | 13.86 KB |
Susanoo | 'Execut<dynamic> (Static)' | dynamic | 122.68 us | 8 | 2.5000 | 0.7500 | 0.2500 | 15.03 KB |
Massive | 'Query (dynamic)' | dynamic | 122.82 us | 8 | 2.3750 | 0.8750 | 0.2500 | 14.25 KB |
ServiceStack | SingleById<T> | Post | 123.93 us | 8 | 3.0000 | 0.7500 | 0.2500 | 17.59 KB |
LINQ to DB | First | Post | 124.53 us | 8 | 1.1250 | 0.1250 | - | 5.53 KB |
SmartSql | QuerySingleSqlParameterCollection | Post | 125.26 us | 8 | 2.5000 | 0.7500 | 0.2500 | 15.48 KB |
SmartSql | QuerySingle | Post | 126.79 us | 9 | 2.5000 | 0.7500 | 0.2500 | 15.59 KB |
LINQ to SQL | 'First (Compiled)' | Post | 127.17 us | 9 | 2.0000 | - | - | 9.87 KB |
SmartSql | GetById | Post | 127.24 us | 9 | 2.7500 | 0.7500 | 0.2500 | 15.89 KB |
SmartSql | QuerySingleStrongRequest | Post | 127.70 us | 9 | 2.5000 | 0.7500 | 0.2500 | 15.51 KB |
SmartSql | QuerySingleFromXml | Post | 128.27 us | 9 | 2.7500 | 0.7500 | 0.2500 | 16.23 KB |
Susanoo | 'Execute<T> (Static)' | Post | 128.92 us | 9 | 2.5000 | 0.7500 | 0.2500 | 15.05 KB |
SmartSql | QuerySingleStrongRequest<dynamic> | dynamic | 129.88 us | 9 | 2.7500 | 1.0000 | 0.5000 | 16.54 KB |
SmartSql | QuerySingleSqlParameterCollection<dynamic> | dynamic | 130.96 us | 9 | 2.5000 | 0.7500 | 0.2500 | 16.51 KB |
Dapper | 'Contrib Get<T>' | Post | 132.10 us | 9 | 2.2500 | 1.0000 | 0.2500 | 14.51 KB |
DevExpress.XPO | FindObject<T> | Post | 137.14 us | 10 | 6.5000 | 0.2500 | - | 29.97 KB |
Susanoo | 'Execute<dynamic> (Cache)' | dynamic | 140.24 us | 11 | 3.2500 | 1.0000 | 0.5000 | 20.48 KB |
Susanoo | 'Execute<T> (Cache)' | Post | 141.23 us | 11 | 3.2500 | 0.7500 | 0.2500 | 20.96 KB |
EF 6 | SqlQuery | Post | 154.68 us | 12 | 4.7500 | 0.7500 | - | 27.96 KB |
DevExpress.XPO | GetObjectByKey<T> | Post | 160.87 us | 13 | 5.2500 | 1.2500 | - | 32.35 KB |
IBatis | QueryForObject | Post | 163.87 us | 14 | 2.7500 | 0.7500 | 0.2500 | 16.59 KB |
Dapper | 'Query<T> (unbuffered)' | Post | 166.28 us | 15 | 2.2500 | 0.7500 | 0.2500 | 13.89 KB |
Dapper | 'Query<dynamic> (unbuffered)' | dynamic | 171.82 us | 16 | 2.2500 | 0.7500 | 0.2500 | 13.93 KB |
DevExpress.XPO | Query<T> | Post | 172.38 us | 16 | 7.5000 | 0.2500 | - | 35.02 KB |
FreeSql | FromSqlFirstDynamic | dynamic | 180.44 us | 17 | 3.2500 | 0.7500 | 0.2500 | 19.38 KB |
EF Core | 'First (Compiled)' | Post | 188.02 us | 18 | 3.5000 | - | - | 16.14 KB |
FreeSql | FromSqlFirst | Post | 196.92 us | 19 | 3.2500 | 0.7500 | 0.2500 | 19.17 KB |
NHibernate | Get<T> | Post | 201.46 us | 20 | 5.7500 | 0.7500 | - | 32.62 KB |
NHibernate | HQL | Post | 207.57 us | 21 | 5.5000 | 0.7500 | - | 35.11 KB |
Chloe | First | Post | 209.26 us | 21 | 5.0000 | 0.7500 | 0.2500 | 29.85 KB |
EF Core | SqlQuery | Post | 234.51 us | 22 | 4.0000 | - | - | 20.64 KB |
EF Core | First | Post | 238.67 us | 23 | 4.2500 | - | - | 20.33 KB |
EF 6 | First | Post | 243.86 us | 24 | 10.5000 | - | - | 48.44 KB |
LINQ to SQL | ExecuteQuery | Post | 250.54 us | 25 | 7.0000 | 1.0000 | 0.5000 | 42.48 KB |
EF Core | 'First (No Tracking)' | Post | 250.59 us | 25 | 3.7500 | 0.7500 | 0.2500 | 21.44 KB |
NHibernate | Criteria | Post | 256.87 us | 26 | 11.0000 | 1.0000 | - | 65.64 KB |
EF 6 | 'First (No Tracking)' | Post | 314.69 us | 27 | 9.0000 | 1.0000 | - | 55.27 KB |
NHibernate | SQL | Post | 336.02 us | 28 | 19.0000 | 1.0000 | - | 101.4 KB |
FreeSql | First | Post | 429.83 us | 29 | 5.0000 | 1.0000 | 0.5000 | 31.56 KB |
SqlSugar | First | Post | 583.49 us | 30 | 10.0000 | 1.0000 | - | 62.5 KB |
LINQ to SQL | First | Post | 761.03 us | 31 | 3.0000 | 1.0000 | - | 14.7 KB |
NHibernate | LINQ | Post | 778.43 us | 32 | 10.0000 | 2.0000 | - | 64.03 KB |