diff --git a/Dapper.Tests.Performance/Benchmarks.Belgrade.cs b/Dapper.Tests.Performance/Benchmarks.Belgrade.cs index 08239bb377a06cae6181fb57df7c403328be1814..3c80d8183107e9930d5e7dcae4ecd0e1789e96d3 100644 --- a/Dapper.Tests.Performance/Benchmarks.Belgrade.cs +++ b/Dapper.Tests.Performance/Benchmarks.Belgrade.cs @@ -15,12 +15,12 @@ public void Setup() _mapper = new QueryMapper(ConnectionString); } - [Benchmark(Description = "Belgrade: ExecuteReader", OperationsPerInvoke = Iterations)] - public Task ExecuteReader() + [Benchmark(Description = "ExecuteReader", OperationsPerInvoke = Iterations)] + public async 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, + await _mapper.ExecuteReader("SELECT TOP 1 * FROM Posts WHERE Id = " + i, reader => { var post = new Post(); diff --git a/Dapper.Tests.Performance/Benchmarks.Dapper.cs b/Dapper.Tests.Performance/Benchmarks.Dapper.cs index 96307d289cf6bc3e359e2a582515d51dfeb1c5af..3fb0df127bc63d7385ebf3f2acedd0cc7415e81b 100644 --- a/Dapper.Tests.Performance/Benchmarks.Dapper.cs +++ b/Dapper.Tests.Performance/Benchmarks.Dapper.cs @@ -12,50 +12,47 @@ public void Setup() BaseSetup(); } - [Benchmark(Description = "Dapper: Query (buffered)", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Query (buffered)", OperationsPerInvoke = Iterations)] public Post QueryBuffered() { Step(); return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First(); } - - [Benchmark(Description = "Dapper: Query (unbuffered)", OperationsPerInvoke = Iterations)] - public Post QueryUnbuffered() + [Benchmark(Description = "Query (buffered)", OperationsPerInvoke = Iterations)] + public dynamic QueryBufferedDynamic() { Step(); - return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); + return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First(); } - [Benchmark(Description = "Dapper: QueryFirstOrDefault", OperationsPerInvoke = Iterations)] - public Post QueryFirstOrDefault() + [Benchmark(Description = "Query (unbuffered)", OperationsPerInvoke = Iterations)] + public Post QueryUnbuffered() { Step(); - return _connection.QueryFirstOrDefault("select * from Posts where Id = @Id", new { Id = i }); + return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); } - - [Benchmark(Description = "Dapper: Query (buffered)", OperationsPerInvoke = Iterations)] - public object QueryBufferedDynamic() + [Benchmark(Description = "Query (unbuffered)", OperationsPerInvoke = Iterations)] + public dynamic QueryUnbufferedDynamic() { Step(); - return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First(); + return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); } - [Benchmark(Description = "Dapper: Query (unbuffered)", OperationsPerInvoke = Iterations)] - public object QueryUnbufferedDynamic() + [Benchmark(Description = "QueryFirstOrDefault", OperationsPerInvoke = Iterations)] + public Post QueryFirstOrDefault() { Step(); - return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); + return _connection.QueryFirstOrDefault("select * from Posts where Id = @Id", new { Id = i }); } - - [Benchmark(Description = "Dapper: QueryFirstOrDefault", OperationsPerInvoke = Iterations)] - public object QueryFirstOrDefaultDynamic() + [Benchmark(Description = "QueryFirstOrDefault", OperationsPerInvoke = Iterations)] + public dynamic QueryFirstOrDefaultDynamic() { Step(); return _connection.QueryFirstOrDefault("select * from Posts where Id = @Id", new { Id = i }).First(); } - - [Benchmark(Description = "Dapper: Contrib Get", OperationsPerInvoke = Iterations)] - public object ContribGet() + + [Benchmark(Description = "Contrib Get", OperationsPerInvoke = Iterations)] + public Post ContribGet() { Step(); return _connection.Get(i); diff --git a/Dapper.Tests.Performance/Benchmarks.EntityFramework.cs b/Dapper.Tests.Performance/Benchmarks.EntityFramework.cs index dee82ccd579656417d7328dcbacba8199fe990c8..0898be186d7d5f548760da40c12b478ced3890d0 100644 --- a/Dapper.Tests.Performance/Benchmarks.EntityFramework.cs +++ b/Dapper.Tests.Performance/Benchmarks.EntityFramework.cs @@ -6,7 +6,7 @@ namespace Dapper.Tests.Performance { - public class EntityFrameworkBenchmarks : BenchmarkBase + public class EF6Benchmarks : BenchmarkBase { private EntityFramework.EFContext Context; private static readonly Func compiledQuery = @@ -19,21 +19,21 @@ public void Setup() Context = new EntityFramework.EFContext(_connection); } - [Benchmark(Description = "EF6: Normal", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Normal", OperationsPerInvoke = Iterations)] public Post Normal() { Step(); return Context.Posts.First(p => p.Id == i); } - [Benchmark(Description = "EF6: SqlQuery", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "SqlQuery", OperationsPerInvoke = Iterations)] public Post SqlQuery() { Step(); return Context.Database.SqlQuery("select * from Posts where Id = {0}", i).First(); } - [Benchmark(Description = "EF6: No Tracking", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "No Tracking", OperationsPerInvoke = Iterations)] public Post NoTracking() { Step(); diff --git a/Dapper.Tests.Performance/Benchmarks.HandCoded.cs b/Dapper.Tests.Performance/Benchmarks.HandCoded.cs index 7dd45a66bf358c38d89bd1792afb56fa2a4b893f..96b14f5db2c822097b045de43c1e96dd554729a0 100644 --- a/Dapper.Tests.Performance/Benchmarks.HandCoded.cs +++ b/Dapper.Tests.Performance/Benchmarks.HandCoded.cs @@ -47,8 +47,8 @@ public void Setup() #endif } - [Benchmark(Description = "HandCoded: SqlCommand", OperationsPerInvoke = Iterations)] - public dynamic SqlCommand() + [Benchmark(Description = "SqlCommand", OperationsPerInvoke = Iterations, Baseline = true)] + public Post SqlCommand() { Step(); _idParam.Value = i; @@ -75,8 +75,8 @@ public dynamic SqlCommand() } } - [Benchmark(Description = "HandCoded: DataTable", OperationsPerInvoke = Iterations)] - public dynamic DataTable() + [Benchmark(Description = "DataTable", OperationsPerInvoke = Iterations)] + public dynamic DataTableDynamic() { Step(); _idParam.Value = i; diff --git a/Dapper.Tests.Performance/Benchmarks.Linq2Sql.cs b/Dapper.Tests.Performance/Benchmarks.Linq2Sql.cs index c8a3b67facfa518783991f9d066852f0d91ec768..bea4ff45191c60acbaab958f05b17aa06f44ba87 100644 --- a/Dapper.Tests.Performance/Benchmarks.Linq2Sql.cs +++ b/Dapper.Tests.Performance/Benchmarks.Linq2Sql.cs @@ -19,21 +19,21 @@ public void Setup() Linq2SqlContext = new DataClassesDataContext(_connection); } - [Benchmark(Description = "Linq2Sql: Normal", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Normal", OperationsPerInvoke = Iterations)] public Linq2Sql.Post Normal() { Step(); return Linq2SqlContext.Posts.First(p => p.Id == i); } - [Benchmark(Description = "Linq2Sql: Compiled", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Compiled", OperationsPerInvoke = Iterations)] public Linq2Sql.Post Compiled() { Step(); return compiledQuery(Linq2SqlContext, i); } - [Benchmark(Description = "Linq2Sql: ExecuteQuery", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "ExecuteQuery", OperationsPerInvoke = Iterations)] public Post ExecuteQuery() { Step(); diff --git a/Dapper.Tests.Performance/Benchmarks.Massive.cs b/Dapper.Tests.Performance/Benchmarks.Massive.cs index 839e22b23f81a1fca399ea5b7ab7f0dbef2a5525..83967869bf2e4b2bf89d883f5bc446f977ac4c61 100644 --- a/Dapper.Tests.Performance/Benchmarks.Massive.cs +++ b/Dapper.Tests.Performance/Benchmarks.Massive.cs @@ -15,8 +15,8 @@ public void Setup() _model = new DynamicModel(ConnectionString); } - [Benchmark(Description = "Massive: Query (dynamic)", OperationsPerInvoke = Iterations)] - public dynamic Query() + [Benchmark(Description = "Query (dynamic)", OperationsPerInvoke = Iterations)] + public dynamic QueryDynamic() { Step(); return _model.Query("select * from Posts where Id = @0", _connection, i).First(); diff --git a/Dapper.Tests.Performance/Benchmarks.NHibernate.cs b/Dapper.Tests.Performance/Benchmarks.NHibernate.cs index 2f12d886143c98b1db58ba21a01576cd52e06ba8..ca6a9b64d2819c1c83c7203cffcbddc6d4d9028a 100644 --- a/Dapper.Tests.Performance/Benchmarks.NHibernate.cs +++ b/Dapper.Tests.Performance/Benchmarks.NHibernate.cs @@ -24,7 +24,7 @@ public void Setup() _get = NHibernateHelper.OpenSession(); } - [Benchmark(Description = "NHibernate: SQL", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "SQL", OperationsPerInvoke = Iterations)] public Post SQL() { Step(); @@ -34,7 +34,7 @@ public Post SQL() .List()[0]; } - [Benchmark(Description = "NHibernate: HQL", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "HQL", OperationsPerInvoke = Iterations)] public Post HQL() { Step(); @@ -43,7 +43,7 @@ public Post HQL() .List()[0]; } - [Benchmark(Description = "NHibernate: Criteria", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Criteria", OperationsPerInvoke = Iterations)] public Post Criteria() { Step(); @@ -52,14 +52,14 @@ public Post Criteria() .List()[0]; } - [Benchmark(Description = "NHibernate: LINQ", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "LINQ", OperationsPerInvoke = Iterations)] public Post LINQ() { Step(); return _linq.Query().First(p => p.Id == i); } - [Benchmark(Description = "NHibernate: Get", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Get", OperationsPerInvoke = Iterations)] public Post Get() { Step(); diff --git a/Dapper.Tests.Performance/Benchmarks.PetaPoco.cs b/Dapper.Tests.Performance/Benchmarks.PetaPoco.cs index d7e876bf845a26600ef938d05048d4e262eabaca..1fce2ebe8f41a8563d882f47b6d93953d287fa04 100644 --- a/Dapper.Tests.Performance/Benchmarks.PetaPoco.cs +++ b/Dapper.Tests.Performance/Benchmarks.PetaPoco.cs @@ -21,15 +21,15 @@ public void Setup() _dbFast.ForceDateTimesToUtc = false; } - [Benchmark(Description = "PetaPoco: Fetch", OperationsPerInvoke = Iterations)] - public dynamic Fetch() + [Benchmark(Description = "Fetch", OperationsPerInvoke = Iterations)] + public Post Fetch() { Step(); return _db.Fetch("SELECT * from Posts where Id=@0", i).First(); } - [Benchmark(Description = "PetaPoco: Fetch (Fast)", OperationsPerInvoke = Iterations)] - public dynamic FetchFast() + [Benchmark(Description = "Fetch (Fast)", OperationsPerInvoke = Iterations)] + public Post FetchFast() { Step(); return _dbFast.Fetch("SELECT * from Posts where Id=@0", i).First(); diff --git a/Dapper.Tests.Performance/Benchmarks.ServiceStack.cs b/Dapper.Tests.Performance/Benchmarks.ServiceStack.cs index 6033c118def6b2ca1b346de9090bef33191085a0..442b06b2ba31ef96e03ad3fc7c49a1f24a2623af 100644 --- a/Dapper.Tests.Performance/Benchmarks.ServiceStack.cs +++ b/Dapper.Tests.Performance/Benchmarks.ServiceStack.cs @@ -16,7 +16,7 @@ public void Setup() _db = dbFactory.Open(); } - [Benchmark(Description = "ServiceStack.OrmLite: SingleById", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "SingleById", OperationsPerInvoke = Iterations)] public Post Query() { Step(); diff --git a/Dapper.Tests.Performance/Benchmarks.Soma.cs b/Dapper.Tests.Performance/Benchmarks.Soma.cs index ddc94a950e0a2aff028b71d76b5873cf581a5b4e..9c388f928e8eddf771adae5a757330884b83db2b 100644 --- a/Dapper.Tests.Performance/Benchmarks.Soma.cs +++ b/Dapper.Tests.Performance/Benchmarks.Soma.cs @@ -13,8 +13,8 @@ public void Setup() _sdb = Simple.Data.Database.OpenConnection(ConnectionString); } - [Benchmark(Description = "Soma: FindById", OperationsPerInvoke = Iterations)] - public dynamic Query() + [Benchmark(Description = "FindById", OperationsPerInvoke = Iterations)] + public dynamic QueryDynamic() { Step(); return _sdb.Posts.FindById(i).FirstOrDefault(); diff --git a/Dapper.Tests.Performance/Benchmarks.Susanoo.cs b/Dapper.Tests.Performance/Benchmarks.Susanoo.cs index 38bdb2330c8d3b70a968548b1d0d8dc89c657c77..aead42be0b52643abc8985119bb90a1849ec7baf 100644 --- a/Dapper.Tests.Performance/Benchmarks.Susanoo.cs +++ b/Dapper.Tests.Performance/Benchmarks.Susanoo.cs @@ -25,7 +25,7 @@ public void Setup() _db = new DatabaseManager(_connection); } - [Benchmark(Description = "Susanoo: Mapping Cache", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Mapping Cache", OperationsPerInvoke = Iterations)] public Post MappingCache() { Step(); @@ -35,7 +35,7 @@ public Post MappingCache() .Execute(_db, new { Id = i }).First(); } - [Benchmark(Description = "Susanoo: Mapping Cache (dynamic)", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Mapping Cache (dynamic)", OperationsPerInvoke = Iterations)] public dynamic MappingCacheDynamic() { Step(); @@ -45,14 +45,14 @@ public dynamic MappingCacheDynamic() .Execute(_db, new { Id = i }).First(); } - [Benchmark(Description = "Susanoo: Mapping Static", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Mapping Static", OperationsPerInvoke = Iterations)] public Post MappingStatic() { Step(); return _cmd.Execute(_db, new { Id = i }).First(); } - [Benchmark(Description = "Susanoo: Mapping Static (dynamic)", OperationsPerInvoke = Iterations)] + [Benchmark(Description = "Mapping Static (dynamic)", OperationsPerInvoke = Iterations)] public dynamic MappingStaticDynamic() { Step(); diff --git a/Dapper.Tests.Performance/Benchmarks.cs b/Dapper.Tests.Performance/Benchmarks.cs index 40284171366ffd01b9e3ea1af445fecef92b30cf..1467c6aeb81ea2407961019357a475ca0c9fae0f 100644 --- a/Dapper.Tests.Performance/Benchmarks.cs +++ b/Dapper.Tests.Performance/Benchmarks.cs @@ -1,12 +1,20 @@ using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Attributes.Columns; +using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Horology; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Order; +using Dapper.Tests.Performance.Helpers; using System; using System.Configuration; using System.Data.SqlClient; namespace Dapper.Tests.Performance { + [OrderProvider(SummaryOrderPolicy.FastestToSlowest)] + [RankColumn] [Config(typeof(Config))] public abstract class BenchmarkBase { @@ -14,7 +22,6 @@ public abstract class BenchmarkBase protected static readonly Random _rand = new Random(); protected SqlConnection _connection; public static string ConnectionString { get; } = ConfigurationManager.ConnectionStrings["Main"].ConnectionString; - protected int i; protected void BaseSetup() @@ -36,6 +43,14 @@ public class Config : ManualConfig public Config() { Add(new MemoryDiagnoser()); + Add(new ORMColum()); + Add(new ReturnColum()); + Add(Job.Default + .WithLaunchCount(1) + .WithIterationTime(new TimeInterval(500, TimeUnit.Millisecond)) + .WithWarmupCount(3) + .WithTargetCount(3) + ); } } } \ No newline at end of file diff --git a/Dapper.Tests.Performance/Helpers/ORMColum.cs b/Dapper.Tests.Performance/Helpers/ORMColum.cs new file mode 100644 index 0000000000000000000000000000000000000000..484d1416601d398f23e30cb25545fd63201c7e45 --- /dev/null +++ b/Dapper.Tests.Performance/Helpers/ORMColum.cs @@ -0,0 +1,25 @@ +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; + +namespace Dapper.Tests.Performance.Helpers +{ + public class ORMColum : IColumn + { + public string Id => nameof(ORMColum); + public string ColumnName { get; } = "ORM"; + public string Legend => "The object relational mapper being tested"; + + public bool IsDefault(Summary summary, Benchmark benchmark) => false; + public string GetValue(Summary summary, Benchmark benchmark) => benchmark.Target.Method.DeclaringType.Name.Replace("Benchmarks", string.Empty); + public string GetValue(Summary summary, Benchmark benchmark, ISummaryStyle style) => benchmark.Target.Method.DeclaringType.Name.Replace("Benchmarks", string.Empty); + + public bool IsAvailable(Summary summary) => true; + public bool AlwaysShow => true; + public ColumnCategory Category => ColumnCategory.Job; + public int PriorityInCategory => -10; + public bool IsNumeric => false; + public UnitType UnitType => UnitType.Dimensionless; + public override string ToString() => ColumnName; + } +} diff --git a/Dapper.Tests.Performance/Helpers/ReturnColum.cs b/Dapper.Tests.Performance/Helpers/ReturnColum.cs new file mode 100644 index 0000000000000000000000000000000000000000..26105c4fed63e22b3a7d520fd3ec503ffc114509 --- /dev/null +++ b/Dapper.Tests.Performance/Helpers/ReturnColum.cs @@ -0,0 +1,25 @@ +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; + +namespace Dapper.Tests.Performance.Helpers +{ + public class ReturnColum : IColumn + { + public string Id => nameof(ReturnColum); + public string ColumnName { get; } = "Return"; + public string Legend => "The return type of the method"; + + public bool IsDefault(Summary summary, Benchmark benchmark) => false; + public string GetValue(Summary summary, Benchmark benchmark) => benchmark.Target.Method.ReturnType.Name; + public string GetValue(Summary summary, Benchmark benchmark, ISummaryStyle style) => benchmark.Target.Method.ReturnType.Name; + + public bool IsAvailable(Summary summary) => true; + public bool AlwaysShow => true; + public ColumnCategory Category => ColumnCategory.Job; + public int PriorityInCategory => 1; + public bool IsNumeric => false; + public UnitType UnitType => UnitType.Dimensionless; + public override string ToString() => ColumnName; + } +}