Commit d3ab338c authored by Nick Craver's avatar Nick Craver

Benchmarks: customization and formatting

More cleanup to do (removing Type column next), but getting to some very
usable output now.
parent d72ae17a
...@@ -15,12 +15,12 @@ public void Setup() ...@@ -15,12 +15,12 @@ public void Setup()
_mapper = new QueryMapper(ConnectionString); _mapper = new QueryMapper(ConnectionString);
} }
[Benchmark(Description = "Belgrade: ExecuteReader", OperationsPerInvoke = Iterations)] [Benchmark(Description = "ExecuteReader", OperationsPerInvoke = Iterations)]
public Task ExecuteReader() public async Task ExecuteReader()
{ {
Step(); Step();
// TODO: How do you get a Post out of this thing? // 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 => reader =>
{ {
var post = new Post(); var post = new Post();
......
...@@ -12,50 +12,47 @@ public void Setup() ...@@ -12,50 +12,47 @@ public void Setup()
BaseSetup(); BaseSetup();
} }
[Benchmark(Description = "Dapper: Query<T> (buffered)", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Query<T> (buffered)", OperationsPerInvoke = Iterations)]
public Post QueryBuffered() public Post QueryBuffered()
{ {
Step(); Step();
return _connection.Query<Post>("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First(); return _connection.Query<Post>("select * from Posts where Id = @Id", new { Id = i }, buffered: true).First();
} }
[Benchmark(Description = "Query<dyanmic> (buffered)", OperationsPerInvoke = Iterations)]
[Benchmark(Description = "Dapper: Query<T> (unbuffered)", OperationsPerInvoke = Iterations)] public dynamic QueryBufferedDynamic()
public Post QueryUnbuffered()
{ {
Step(); Step();
return _connection.Query<Post>("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<T>", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Query<T> (unbuffered)", OperationsPerInvoke = Iterations)]
public Post QueryFirstOrDefault() public Post QueryUnbuffered()
{ {
Step(); Step();
return _connection.QueryFirstOrDefault<Post>("select * from Posts where Id = @Id", new { Id = i }); return _connection.Query<Post>("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First();
} }
[Benchmark(Description = "Query<dyanmic> (unbuffered)", OperationsPerInvoke = Iterations)]
[Benchmark(Description = "Dapper: Query<dyanmic> (buffered)", OperationsPerInvoke = Iterations)] public dynamic QueryUnbufferedDynamic()
public object QueryBufferedDynamic()
{ {
Step(); 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<dyanmic> (unbuffered)", OperationsPerInvoke = Iterations)] [Benchmark(Description = "QueryFirstOrDefault<T>", OperationsPerInvoke = Iterations)]
public object QueryUnbufferedDynamic() public Post QueryFirstOrDefault()
{ {
Step(); Step();
return _connection.Query("select * from Posts where Id = @Id", new { Id = i }, buffered: false).First(); return _connection.QueryFirstOrDefault<Post>("select * from Posts where Id = @Id", new { Id = i });
} }
[Benchmark(Description = "QueryFirstOrDefault<dyanmic>", OperationsPerInvoke = Iterations)]
[Benchmark(Description = "Dapper: QueryFirstOrDefault<dyanmic>", OperationsPerInvoke = Iterations)] public dynamic QueryFirstOrDefaultDynamic()
public object QueryFirstOrDefaultDynamic()
{ {
Step(); Step();
return _connection.QueryFirstOrDefault("select * from Posts where Id = @Id", new { Id = i }).First(); return _connection.QueryFirstOrDefault("select * from Posts where Id = @Id", new { Id = i }).First();
} }
[Benchmark(Description = "Dapper: Contrib Get<T>", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Contrib Get<T>", OperationsPerInvoke = Iterations)]
public object ContribGet() public Post ContribGet()
{ {
Step(); Step();
return _connection.Get<Post>(i); return _connection.Get<Post>(i);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
namespace Dapper.Tests.Performance namespace Dapper.Tests.Performance
{ {
public class EntityFrameworkBenchmarks : BenchmarkBase public class EF6Benchmarks : BenchmarkBase
{ {
private EntityFramework.EFContext Context; private EntityFramework.EFContext Context;
private static readonly Func<DataClassesDataContext, int, Linq2Sql.Post> compiledQuery = private static readonly Func<DataClassesDataContext, int, Linq2Sql.Post> compiledQuery =
...@@ -19,21 +19,21 @@ public void Setup() ...@@ -19,21 +19,21 @@ public void Setup()
Context = new EntityFramework.EFContext(_connection); Context = new EntityFramework.EFContext(_connection);
} }
[Benchmark(Description = "EF6: Normal", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Normal", OperationsPerInvoke = Iterations)]
public Post Normal() public Post Normal()
{ {
Step(); Step();
return Context.Posts.First(p => p.Id == i); return Context.Posts.First(p => p.Id == i);
} }
[Benchmark(Description = "EF6: SqlQuery", OperationsPerInvoke = Iterations)] [Benchmark(Description = "SqlQuery", OperationsPerInvoke = Iterations)]
public Post SqlQuery() public Post SqlQuery()
{ {
Step(); Step();
return Context.Database.SqlQuery<Post>("select * from Posts where Id = {0}", i).First(); return Context.Database.SqlQuery<Post>("select * from Posts where Id = {0}", i).First();
} }
[Benchmark(Description = "EF6: No Tracking", OperationsPerInvoke = Iterations)] [Benchmark(Description = "No Tracking", OperationsPerInvoke = Iterations)]
public Post NoTracking() public Post NoTracking()
{ {
Step(); Step();
......
...@@ -47,8 +47,8 @@ public void Setup() ...@@ -47,8 +47,8 @@ public void Setup()
#endif #endif
} }
[Benchmark(Description = "HandCoded: SqlCommand", OperationsPerInvoke = Iterations)] [Benchmark(Description = "SqlCommand", OperationsPerInvoke = Iterations, Baseline = true)]
public dynamic SqlCommand() public Post SqlCommand()
{ {
Step(); Step();
_idParam.Value = i; _idParam.Value = i;
...@@ -75,8 +75,8 @@ public dynamic SqlCommand() ...@@ -75,8 +75,8 @@ public dynamic SqlCommand()
} }
} }
[Benchmark(Description = "HandCoded: DataTable", OperationsPerInvoke = Iterations)] [Benchmark(Description = "DataTable", OperationsPerInvoke = Iterations)]
public dynamic DataTable() public dynamic DataTableDynamic()
{ {
Step(); Step();
_idParam.Value = i; _idParam.Value = i;
......
...@@ -19,21 +19,21 @@ public void Setup() ...@@ -19,21 +19,21 @@ public void Setup()
Linq2SqlContext = new DataClassesDataContext(_connection); Linq2SqlContext = new DataClassesDataContext(_connection);
} }
[Benchmark(Description = "Linq2Sql: Normal", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Normal", OperationsPerInvoke = Iterations)]
public Linq2Sql.Post Normal() public Linq2Sql.Post Normal()
{ {
Step(); Step();
return Linq2SqlContext.Posts.First(p => p.Id == i); return Linq2SqlContext.Posts.First(p => p.Id == i);
} }
[Benchmark(Description = "Linq2Sql: Compiled", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Compiled", OperationsPerInvoke = Iterations)]
public Linq2Sql.Post Compiled() public Linq2Sql.Post Compiled()
{ {
Step(); Step();
return compiledQuery(Linq2SqlContext, i); return compiledQuery(Linq2SqlContext, i);
} }
[Benchmark(Description = "Linq2Sql: ExecuteQuery", OperationsPerInvoke = Iterations)] [Benchmark(Description = "ExecuteQuery", OperationsPerInvoke = Iterations)]
public Post ExecuteQuery() public Post ExecuteQuery()
{ {
Step(); Step();
......
...@@ -15,8 +15,8 @@ public void Setup() ...@@ -15,8 +15,8 @@ public void Setup()
_model = new DynamicModel(ConnectionString); _model = new DynamicModel(ConnectionString);
} }
[Benchmark(Description = "Massive: Query (dynamic)", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Query (dynamic)", OperationsPerInvoke = Iterations)]
public dynamic Query() public dynamic QueryDynamic()
{ {
Step(); Step();
return _model.Query("select * from Posts where Id = @0", _connection, i).First(); return _model.Query("select * from Posts where Id = @0", _connection, i).First();
......
...@@ -24,7 +24,7 @@ public void Setup() ...@@ -24,7 +24,7 @@ public void Setup()
_get = NHibernateHelper.OpenSession(); _get = NHibernateHelper.OpenSession();
} }
[Benchmark(Description = "NHibernate: SQL", OperationsPerInvoke = Iterations)] [Benchmark(Description = "SQL", OperationsPerInvoke = Iterations)]
public Post SQL() public Post SQL()
{ {
Step(); Step();
...@@ -34,7 +34,7 @@ public Post SQL() ...@@ -34,7 +34,7 @@ public Post SQL()
.List<Post>()[0]; .List<Post>()[0];
} }
[Benchmark(Description = "NHibernate: HQL", OperationsPerInvoke = Iterations)] [Benchmark(Description = "HQL", OperationsPerInvoke = Iterations)]
public Post HQL() public Post HQL()
{ {
Step(); Step();
...@@ -43,7 +43,7 @@ public Post HQL() ...@@ -43,7 +43,7 @@ public Post HQL()
.List<Post>()[0]; .List<Post>()[0];
} }
[Benchmark(Description = "NHibernate: Criteria", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Criteria", OperationsPerInvoke = Iterations)]
public Post Criteria() public Post Criteria()
{ {
Step(); Step();
...@@ -52,14 +52,14 @@ public Post Criteria() ...@@ -52,14 +52,14 @@ public Post Criteria()
.List<Post>()[0]; .List<Post>()[0];
} }
[Benchmark(Description = "NHibernate: LINQ", OperationsPerInvoke = Iterations)] [Benchmark(Description = "LINQ", OperationsPerInvoke = Iterations)]
public Post LINQ() public Post LINQ()
{ {
Step(); Step();
return _linq.Query<Post>().First(p => p.Id == i); return _linq.Query<Post>().First(p => p.Id == i);
} }
[Benchmark(Description = "NHibernate: Get<T>", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Get<T>", OperationsPerInvoke = Iterations)]
public Post Get() public Post Get()
{ {
Step(); Step();
......
...@@ -21,15 +21,15 @@ public void Setup() ...@@ -21,15 +21,15 @@ public void Setup()
_dbFast.ForceDateTimesToUtc = false; _dbFast.ForceDateTimesToUtc = false;
} }
[Benchmark(Description = "PetaPoco: Fetch<Post>", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Fetch<Post>", OperationsPerInvoke = Iterations)]
public dynamic Fetch() public Post Fetch()
{ {
Step(); Step();
return _db.Fetch<Post>("SELECT * from Posts where Id=@0", i).First(); return _db.Fetch<Post>("SELECT * from Posts where Id=@0", i).First();
} }
[Benchmark(Description = "PetaPoco: Fetch<Post> (Fast)", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Fetch<Post> (Fast)", OperationsPerInvoke = Iterations)]
public dynamic FetchFast() public Post FetchFast()
{ {
Step(); Step();
return _dbFast.Fetch<Post>("SELECT * from Posts where Id=@0", i).First(); return _dbFast.Fetch<Post>("SELECT * from Posts where Id=@0", i).First();
......
...@@ -16,7 +16,7 @@ public void Setup() ...@@ -16,7 +16,7 @@ public void Setup()
_db = dbFactory.Open(); _db = dbFactory.Open();
} }
[Benchmark(Description = "ServiceStack.OrmLite: SingleById", OperationsPerInvoke = Iterations)] [Benchmark(Description = "SingleById", OperationsPerInvoke = Iterations)]
public Post Query() public Post Query()
{ {
Step(); Step();
......
...@@ -13,8 +13,8 @@ public void Setup() ...@@ -13,8 +13,8 @@ public void Setup()
_sdb = Simple.Data.Database.OpenConnection(ConnectionString); _sdb = Simple.Data.Database.OpenConnection(ConnectionString);
} }
[Benchmark(Description = "Soma: FindById", OperationsPerInvoke = Iterations)] [Benchmark(Description = "FindById", OperationsPerInvoke = Iterations)]
public dynamic Query() public dynamic QueryDynamic()
{ {
Step(); Step();
return _sdb.Posts.FindById(i).FirstOrDefault(); return _sdb.Posts.FindById(i).FirstOrDefault();
......
...@@ -25,7 +25,7 @@ public void Setup() ...@@ -25,7 +25,7 @@ public void Setup()
_db = new DatabaseManager(_connection); _db = new DatabaseManager(_connection);
} }
[Benchmark(Description = "Susanoo: Mapping Cache", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Mapping Cache", OperationsPerInvoke = Iterations)]
public Post MappingCache() public Post MappingCache()
{ {
Step(); Step();
...@@ -35,7 +35,7 @@ public Post MappingCache() ...@@ -35,7 +35,7 @@ public Post MappingCache()
.Execute(_db, new { Id = i }).First(); .Execute(_db, new { Id = i }).First();
} }
[Benchmark(Description = "Susanoo: Mapping Cache (dynamic)", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Mapping Cache (dynamic)", OperationsPerInvoke = Iterations)]
public dynamic MappingCacheDynamic() public dynamic MappingCacheDynamic()
{ {
Step(); Step();
...@@ -45,14 +45,14 @@ public dynamic MappingCacheDynamic() ...@@ -45,14 +45,14 @@ public dynamic MappingCacheDynamic()
.Execute(_db, new { Id = i }).First(); .Execute(_db, new { Id = i }).First();
} }
[Benchmark(Description = "Susanoo: Mapping Static", OperationsPerInvoke = Iterations)] [Benchmark(Description = "Mapping Static", OperationsPerInvoke = Iterations)]
public Post MappingStatic() public Post MappingStatic()
{ {
Step(); Step();
return _cmd.Execute(_db, new { Id = i }).First(); 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() public dynamic MappingStaticDynamic()
{ {
Step(); Step();
......
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Columns;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs; using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Horology;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Order;
using Dapper.Tests.Performance.Helpers;
using System; using System;
using System.Configuration; using System.Configuration;
using System.Data.SqlClient; using System.Data.SqlClient;
namespace Dapper.Tests.Performance namespace Dapper.Tests.Performance
{ {
[OrderProvider(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
[Config(typeof(Config))] [Config(typeof(Config))]
public abstract class BenchmarkBase public abstract class BenchmarkBase
{ {
...@@ -14,7 +22,6 @@ public abstract class BenchmarkBase ...@@ -14,7 +22,6 @@ public abstract class BenchmarkBase
protected static readonly Random _rand = new Random(); protected static readonly Random _rand = new Random();
protected SqlConnection _connection; protected SqlConnection _connection;
public static string ConnectionString { get; } = ConfigurationManager.ConnectionStrings["Main"].ConnectionString; public static string ConnectionString { get; } = ConfigurationManager.ConnectionStrings["Main"].ConnectionString;
protected int i; protected int i;
protected void BaseSetup() protected void BaseSetup()
...@@ -36,6 +43,14 @@ public class Config : ManualConfig ...@@ -36,6 +43,14 @@ public class Config : ManualConfig
public Config() public Config()
{ {
Add(new MemoryDiagnoser()); 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
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;
}
}
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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment