From ea6b193406fb4c96d9748b49165af715a68ad0d6 Mon Sep 17 00:00:00 2001 From: Nick Craver Date: Fri, 12 May 2017 21:14:02 -0400 Subject: [PATCH] Benchmarks: performance and formatting --- .../Benchmarks.Belgrade.cs | 6 +-- Dapper.Tests.Performance/Benchmarks.Dapper.cs | 39 +++++++++---------- .../Benchmarks.EntityFramework.cs | 8 ++-- .../Benchmarks.HandCoded.cs | 8 ++-- .../Benchmarks.Linq2Sql.cs | 6 +-- .../Benchmarks.Massive.cs | 4 +- .../Benchmarks.NHibernate.cs | 10 ++--- .../Benchmarks.PetaPoco.cs | 8 ++-- .../Benchmarks.ServiceStack.cs | 2 +- Dapper.Tests.Performance/Benchmarks.Soma.cs | 4 +- .../Benchmarks.Susanoo.cs | 8 ++-- Dapper.Tests.Performance/Benchmarks.cs | 17 +++++++- Dapper.Tests.Performance/Helpers/ORMColum.cs | 25 ++++++++++++ .../Helpers/ReturnColum.cs | 25 ++++++++++++ 14 files changed, 116 insertions(+), 54 deletions(-) create mode 100644 Dapper.Tests.Performance/Helpers/ORMColum.cs create mode 100644 Dapper.Tests.Performance/Helpers/ReturnColum.cs diff --git a/Dapper.Tests.Performance/Benchmarks.Belgrade.cs b/Dapper.Tests.Performance/Benchmarks.Belgrade.cs index 08239bb..3c80d81 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 96307d2..3fb0df1 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 dee82cc..0898be1 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 23e6c57..6d30262 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 c8a3b67..bea4ff4 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 839e22b..8396786 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 2f12d88..ca6a9b6 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 d7e876b..de91ec6 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 = "(Fast) Fetch", 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 6033c11..7029aa5 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 ddc94a9..4934378 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 (dynamic)", 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 38bdb23..946c1e0 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 4028417..1467c6a 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 0000000..a2e6101 --- /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 0000000..26105c4 --- /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; + } +} -- GitLab