-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Benchmarks v2: BenchmarkDotNet and friends
This is based on BenchmarkDotNet (while preserving the legacy format with minor improvements as well - legacy runs much faster). See #666 for details. Not an ominus number at all. Note: this code will get a bit simpler with BenchmarkDotNet categories, see dotnet/BenchmarkDotNet#248 for details.
- Loading branch information
1 parent
4915071
commit 0a8fcd9
Showing
16 changed files
with
761 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Belgrade.SqlClient.SqlDb; | ||
using System.Threading.Tasks; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class BelgradeBenchmarks : BenchmarkBase | ||
{ | ||
private QueryMapper _mapper; | ||
|
||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
_mapper = new QueryMapper(ConnectionString); | ||
} | ||
|
||
[Benchmark(Description = "Belgrade: ExecuteReader", OperationsPerInvoke = Iterations)] | ||
public Task ExecuteReader() | ||
{ | ||
Step(); | ||
// TODO: How do you get a Post out of this thing? | ||
return _mapper.ExecuteReader("SELECT TOP 1 * FROM Posts WHERE Id = " + i, | ||
reader => | ||
{ | ||
var post = new Post(); | ||
post.Id = reader.GetInt32(0); | ||
post.Text = reader.GetString(1); | ||
post.CreationDate = reader.GetDateTime(2); | ||
post.LastChangeDate = reader.GetDateTime(3); | ||
|
||
post.Counter1 = reader.IsDBNull(4) ? null : (int?)reader.GetInt32(4); | ||
post.Counter2 = reader.IsDBNull(5) ? null : (int?)reader.GetInt32(5); | ||
post.Counter3 = reader.IsDBNull(6) ? null : (int?)reader.GetInt32(6); | ||
post.Counter4 = reader.IsDBNull(7) ? null : (int?)reader.GetInt32(7); | ||
post.Counter5 = reader.IsDBNull(8) ? null : (int?)reader.GetInt32(8); | ||
post.Counter6 = reader.IsDBNull(9) ? null : (int?)reader.GetInt32(9); | ||
post.Counter7 = reader.IsDBNull(10) ? null : (int?)reader.GetInt32(10); | ||
post.Counter8 = reader.IsDBNull(11) ? null : (int?)reader.GetInt32(11); | ||
post.Counter9 = reader.IsDBNull(12) ? null : (int?)reader.GetInt32(12); | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Dapper.Contrib.Extensions; | ||
using System.Linq; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class DapperBenchmarks : BenchmarkBase | ||
{ | ||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: Query<T> (buffered)", OperationsPerInvoke = Iterations)] | ||
public Post QueryBuffered() | ||
{ | ||
Step(); | ||
return _connection.Query<Post>("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First(); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: Query<T> (unbuffered)", OperationsPerInvoke = Iterations)] | ||
public Post QueryUnbuffered() | ||
{ | ||
Step(); | ||
return _connection.Query<Post>("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: QueryFirstOrDefault<T>", OperationsPerInvoke = Iterations)] | ||
public Post QueryFirstOrDefault() | ||
{ | ||
Step(); | ||
return _connection.QueryFirstOrDefault<Post>("select * from Posts where Id = @Id", new { Id = i }); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: Query<dyanmic> (buffered)", OperationsPerInvoke = Iterations)] | ||
public object QueryBufferedDynamic() | ||
{ | ||
Step(); | ||
return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First(); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: Query<dyanmic> (unbuffered)", OperationsPerInvoke = Iterations)] | ||
public object QueryUnbufferedDynamic() | ||
{ | ||
Step(); | ||
return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: QueryFirstOrDefault<dyanmic>", OperationsPerInvoke = Iterations)] | ||
public object QueryFirstOrDefaultDynamic() | ||
{ | ||
Step(); | ||
return _connection.QueryFirstOrDefault("select * from Posts where Id = @Id", new { Id = i }).First(); | ||
} | ||
|
||
[Benchmark(Description = "Dapper: Contrib Get<T>", OperationsPerInvoke = Iterations)] | ||
public object ContribGet() | ||
{ | ||
Step(); | ||
return _connection.Get<Post>(i); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Dapper.Tests.Performance.Linq2Sql; | ||
using System; | ||
using System.Data.Linq; | ||
using System.Linq; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class EntityFrameworkBenchmarks : BenchmarkBase | ||
{ | ||
private EntityFramework.EFContext Context; | ||
private static readonly Func<DataClassesDataContext, int, Linq2Sql.Post> compiledQuery = | ||
CompiledQuery.Compile((DataClassesDataContext ctx, int id) => ctx.Posts.First(p => p.Id == id)); | ||
|
||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
Context = new EntityFramework.EFContext(_connection); | ||
} | ||
|
||
[Benchmark(Description = "EF6: Normal", OperationsPerInvoke = Iterations)] | ||
public Post Normal() | ||
{ | ||
Step(); | ||
return Context.Posts.First(p => p.Id == i); | ||
} | ||
|
||
[Benchmark(Description = "EF6: SqlQuery", OperationsPerInvoke = Iterations)] | ||
public Post SqlQuery() | ||
{ | ||
Step(); | ||
return Context.Database.SqlQuery<Post>("select * from Posts where Id = {0}", i).First(); | ||
} | ||
|
||
[Benchmark(Description = "EF6: No Tracking", OperationsPerInvoke = Iterations)] | ||
public Post NoTracking() | ||
{ | ||
Step(); | ||
return Context.Posts.AsNoTracking().First(p => p.Id == i); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using System; | ||
using System.Data; | ||
using System.Data.SqlClient; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class HandCodedBenchmarks : BenchmarkBase | ||
{ | ||
private SqlCommand _postCommand; | ||
private SqlParameter _idParam; | ||
#if !COREFX | ||
private DataTable _table; | ||
#endif | ||
|
||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
_postCommand = new SqlCommand() | ||
{ | ||
Connection = _connection, | ||
CommandText = @"select Id, [Text], [CreationDate], LastChangeDate, | ||
Counter1,Counter2,Counter3,Counter4,Counter5,Counter6,Counter7,Counter8,Counter9 from Posts where Id = @Id" | ||
}; | ||
_idParam = _postCommand.Parameters.Add("@Id", SqlDbType.Int); | ||
#if !COREFX | ||
_table = new DataTable | ||
{ | ||
Columns = | ||
{ | ||
{"Id", typeof (int)}, | ||
{"Text", typeof (string)}, | ||
{"CreationDate", typeof (DateTime)}, | ||
{"LastChangeDate", typeof (DateTime)}, | ||
{"Counter1", typeof (int)}, | ||
{"Counter2", typeof (int)}, | ||
{"Counter3", typeof (int)}, | ||
{"Counter4", typeof (int)}, | ||
{"Counter5", typeof (int)}, | ||
{"Counter6", typeof (int)}, | ||
{"Counter7", typeof (int)}, | ||
{"Counter8", typeof (int)}, | ||
{"Counter9", typeof (int)}, | ||
} | ||
}; | ||
#endif | ||
} | ||
|
||
[Benchmark(Description = "HandCoded: SqlCommand", OperationsPerInvoke = Iterations)] | ||
public dynamic SqlCommand() | ||
{ | ||
Step(); | ||
_idParam.Value = i; | ||
|
||
using (var reader = _postCommand.ExecuteReader()) | ||
{ | ||
reader.Read(); | ||
var post = new Post(); | ||
post.Id = reader.GetInt32(0); | ||
post.Text = reader.GetNullableString(1); | ||
post.CreationDate = reader.GetDateTime(2); | ||
post.LastChangeDate = reader.GetDateTime(3); | ||
|
||
post.Counter1 = reader.GetNullableValue<int>(4); | ||
post.Counter2 = reader.GetNullableValue<int>(5); | ||
post.Counter3 = reader.GetNullableValue<int>(6); | ||
post.Counter4 = reader.GetNullableValue<int>(7); | ||
post.Counter5 = reader.GetNullableValue<int>(8); | ||
post.Counter6 = reader.GetNullableValue<int>(9); | ||
post.Counter7 = reader.GetNullableValue<int>(10); | ||
post.Counter8 = reader.GetNullableValue<int>(11); | ||
post.Counter9 = reader.GetNullableValue<int>(12); | ||
return post; | ||
} | ||
} | ||
|
||
[Benchmark(Description = "HandCoded: DataTable", OperationsPerInvoke = Iterations)] | ||
public dynamic DataTable() | ||
{ | ||
Step(); | ||
_idParam.Value = i; | ||
var values = new object[13]; | ||
using (var reader = _postCommand.ExecuteReader()) | ||
{ | ||
reader.Read(); | ||
reader.GetValues(values); | ||
_table.Rows.Add(values); | ||
return _table.Rows[_table.Rows.Count-1]; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Dapper.Tests.Performance.Linq2Sql; | ||
using System; | ||
using System.Data.Linq; | ||
using System.Linq; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class Linq2SqlBenchmarks : BenchmarkBase | ||
{ | ||
private DataClassesDataContext Linq2SqlContext; | ||
private static readonly Func<DataClassesDataContext, int, Linq2Sql.Post> compiledQuery = | ||
CompiledQuery.Compile((DataClassesDataContext ctx, int id) => ctx.Posts.First(p => p.Id == id)); | ||
|
||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
Linq2SqlContext = new DataClassesDataContext(_connection); | ||
} | ||
|
||
[Benchmark(Description = "Linq2Sql: Normal", OperationsPerInvoke = Iterations)] | ||
public Linq2Sql.Post Normal() | ||
{ | ||
Step(); | ||
return Linq2SqlContext.Posts.First(p => p.Id == i); | ||
} | ||
|
||
[Benchmark(Description = "Linq2Sql: Compiled", OperationsPerInvoke = Iterations)] | ||
public Linq2Sql.Post Compiled() | ||
{ | ||
Step(); | ||
return compiledQuery(Linq2SqlContext, i); | ||
} | ||
|
||
[Benchmark(Description = "Linq2Sql: ExecuteQuery", OperationsPerInvoke = Iterations)] | ||
public Post ExecuteQuery() | ||
{ | ||
Step(); | ||
return Linq2SqlContext.ExecuteQuery<Post>("select * from Posts where Id = {0}", i).First(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Massive; | ||
using System.Linq; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class MassiveBenchmarks : BenchmarkBase | ||
{ | ||
private DynamicModel _model; | ||
|
||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
_model = new DynamicModel(ConnectionString); | ||
} | ||
|
||
[Benchmark(Description = "Massive: Query (dynamic)", OperationsPerInvoke = Iterations)] | ||
public dynamic Query() | ||
{ | ||
Step(); | ||
return _model.Query("select * from Posts where Id = @0", _connection, i).First(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using BenchmarkDotNet.Attributes; | ||
using Dapper.Tests.Performance.NHibernate; | ||
using NHibernate; | ||
using NHibernate.Criterion; | ||
using NHibernate.Linq; | ||
using NHibernate.Transform; | ||
using NHibernate.Util; | ||
using System.Linq; | ||
|
||
namespace Dapper.Tests.Performance | ||
{ | ||
public class NHibernateBenchmarks : BenchmarkBase | ||
{ | ||
private IStatelessSession _sql, _hql, _criteria, _linq, _get; | ||
|
||
[Setup] | ||
public void Setup() | ||
{ | ||
BaseSetup(); | ||
_sql = NHibernateHelper.OpenSession(); | ||
_hql = NHibernateHelper.OpenSession(); | ||
_criteria = NHibernateHelper.OpenSession(); | ||
_linq = NHibernateHelper.OpenSession(); | ||
_get = NHibernateHelper.OpenSession(); | ||
} | ||
|
||
[Benchmark(Description = "NHibernate: SQL", OperationsPerInvoke = Iterations)] | ||
public Post SQL() | ||
{ | ||
Step(); | ||
return _sql.CreateSQLQuery(@"select * from Posts where Id = :id") | ||
.SetInt32("id", i) | ||
.SetResultTransformer(Transformers.AliasToBean<Post>()) | ||
.List<Post>()[0]; | ||
} | ||
|
||
[Benchmark(Description = "NHibernate: HQL", OperationsPerInvoke = Iterations)] | ||
public Post HQL() | ||
{ | ||
Step(); | ||
return _hql.CreateQuery(@"from Post as p where p.Id = :id") | ||
.SetInt32("id", i) | ||
.List<Post>()[0]; | ||
} | ||
|
||
[Benchmark(Description = "NHibernate: Criteria", OperationsPerInvoke = Iterations)] | ||
public Post Criteria() | ||
{ | ||
Step(); | ||
return _criteria.CreateCriteria<Post>() | ||
.Add(Restrictions.IdEq(i)) | ||
.List<Post>()[0]; | ||
} | ||
|
||
[Benchmark(Description = "NHibernate: LINQ", OperationsPerInvoke = Iterations)] | ||
public Post LINQ() | ||
{ | ||
Step(); | ||
return _linq.Query<Post>().First(p => p.Id == i); | ||
} | ||
|
||
[Benchmark(Description = "NHibernate: Get<T>", OperationsPerInvoke = Iterations)] | ||
public Post Get() | ||
{ | ||
Step(); | ||
return _get.Get<Post>(i); | ||
} | ||
} | ||
} |
Oops, something went wrong.