提交 0a8fcd98 编写于 作者: N Nick Craver

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 https://github.com/dotnet/BenchmarkDotNet/issues/248 for details.
上级 49150713
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);
});
}
}
}
\ No newline at end of file
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);
}
}
}
\ No newline at end of file
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);
}
}
}
\ No newline at end of file
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];
}
}
}
}
\ No newline at end of file
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();
}
}
}
\ No newline at end of file
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();
}
}
}
\ No newline at end of file
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);
}
}
}
\ No newline at end of file
using BenchmarkDotNet.Attributes;
using PetaPoco;
using System.Linq;
namespace Dapper.Tests.Performance
{
public class PetaPocoBenchmarks : BenchmarkBase
{
private Database _db, _dbFast;
[Setup]
public void Setup()
{
BaseSetup();
_db = new Database(ConnectionString, "System.Data.SqlClient");
_db.OpenSharedConnection();
_dbFast = new Database(ConnectionString, "System.Data.SqlClient");
_dbFast.OpenSharedConnection();
_dbFast.EnableAutoSelect = false;
_dbFast.EnableNamedParams = false;
_dbFast.ForceDateTimesToUtc = false;
}
[Benchmark(Description = "PetaPoco: Fetch<Post>", OperationsPerInvoke = Iterations)]
public dynamic Fetch()
{
Step();
return _db.Fetch<Post>("SELECT * from Posts where Id=@0", i).First();
}
[Benchmark(Description = "PetaPoco: Fetch<Post> (Fast)", OperationsPerInvoke = Iterations)]
public dynamic FetchFast()
{
Step();
return _dbFast.Fetch<Post>("SELECT * from Posts where Id=@0", i).First();
}
}
}
\ No newline at end of file
using BenchmarkDotNet.Attributes;
using ServiceStack.OrmLite;
using System.Data;
namespace Dapper.Tests.Performance
{
public class ServiceStackBenchmarks : BenchmarkBase
{
private IDbConnection _db;
[Setup]
public void Setup()
{
BaseSetup();
var dbFactory = new OrmLiteConnectionFactory(ConnectionString, SqlServerDialect.Provider);
_db = dbFactory.Open();
}
[Benchmark(Description = "ServiceStack.OrmLite: SingleById", OperationsPerInvoke = Iterations)]
public Post Query()
{
Step();
return _db.SingleById<Post>(i);
}
}
}
\ No newline at end of file
using BenchmarkDotNet.Attributes;
namespace Dapper.Tests.Performance
{
public class SomaBenchmarks : BenchmarkBase
{
private dynamic _sdb;
[Setup]
public void Setup()
{
BaseSetup();
_sdb = Simple.Data.Database.OpenConnection(ConnectionString);
}
[Benchmark(Description = "Soma: FindById", OperationsPerInvoke = Iterations)]
public dynamic Query()
{
Step();
return _sdb.Posts.FindById(i).FirstOrDefault();
}
}
}
\ No newline at end of file
using BenchmarkDotNet.Attributes;
using Susanoo;
using Susanoo.Processing;
using System.Data;
using System.Linq;
namespace Dapper.Tests.Performance
{
public class SusanooBenchmarks : BenchmarkBase
{
private DatabaseManager _db;
private static readonly ISingleResultSetCommandProcessor<dynamic, Post> _cmd =
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<Post>()
.Realize();
private static readonly ISingleResultSetCommandProcessor<dynamic, dynamic> _cmdDynamic =
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<dynamic>()
.Realize();
[Setup]
public void Setup()
{
BaseSetup();
_db = new DatabaseManager(_connection);
}
[Benchmark(Description = "Susanoo: Mapping Cache", OperationsPerInvoke = Iterations)]
public Post MappingCache()
{
Step();
return CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<Post>()
.Realize()
.Execute(_db, new { Id = i }).First();
}
[Benchmark(Description = "Susanoo: Mapping Cache (dynamic)", OperationsPerInvoke = Iterations)]
public dynamic MappingCacheDynamic()
{
Step();
return CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<dynamic>()
.Realize()
.Execute(_db, new { Id = i }).First();
}
[Benchmark(Description = "Susanoo: Mapping Static", OperationsPerInvoke = Iterations)]
public Post MappingStatic()
{
Step();
return _cmd.Execute(_db, new { Id = i }).First();
}
[Benchmark(Description = "Susanoo: Mapping Static (dynamic)", OperationsPerInvoke = Iterations)]
public dynamic MappingStaticDynamic()
{
Step();
return _cmdDynamic.Execute(_db, new { Id = i }).First();
}
}
}
\ No newline at end of file
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using System;
using System.Configuration;
using System.Data.SqlClient;
namespace Dapper.Tests.Performance
{
[Config(typeof(Config))]
public abstract class BenchmarkBase
{
public const int Iterations = 50;
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()
{
i = 0;
_connection = new SqlConnection(ConnectionString);
_connection.Open();
}
protected void Step()
{
i++;
if (i > 5000) i = 1;
}
}
public class Config : ManualConfig
{
public Config()
{
Add(new MemoryDiagnoser());
}
}
}
\ No newline at end of file
......@@ -12,21 +12,23 @@
<ProjectReference Include="..\Dapper.Contrib\Dapper.Contrib.csproj" />
<ProjectReference Include="..\Dapper.EntityFramework\Dapper.EntityFramework.csproj" />
<PackageReference Include="Belgrade.Sql.Client" Version="0.7.0" />
<PackageReference Include="BenchmarkDotNet" Version="0.10.5" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.10.5" />
<!--<PackageReference Include="BLToolkit" Version="4.3.6" />-->
<PackageReference Include="EntityFramework" Version="6.1.3" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="5.8.0" />
<PackageReference Include="FirebirdSql.Data.FirebirdClient" Version="5.9.0.1" />
<PackageReference Include="Microsoft.SqlServer.Compact" Version="4.0.8876.1" />
<PackageReference Include="Microsoft.SqlServer.Types" Version="14.0.314.76" />
<PackageReference Include="MySql.Data" Version="7.0.7-m61" />
<PackageReference Include="NHibernate" Version="4.1.1.4000" />
<PackageReference Include="Npgsql" Version="3.2.2" />
<PackageReference Include="PetaPoco" Version="5.1.244" />
<PackageReference Include="ServiceStack.OrmLite.SqlServer.Signed" Version="4.5.6" />
<PackageReference Include="ServiceStack.OrmLite.SqlServer.Signed" Version="4.5.8" />
<PackageReference Include="Simple.Data.SqlServer" Version="2.0.0-alpha1" />
<PackageReference Include="Soma" Version="1.8.0.7" />
<PackageReference Include="Soma" Version="1.9.0.1" />
<PackageReference Include="SubSonic" Version="3.0.0.4" />
<PackageReference Include="Susanoo.SqlServer" Version="1.2.4.2" />
<PackageReference Include="System.Data.SQLite" Version="1.0.104" />
<PackageReference Include="System.Data.SQLite" Version="1.0.105" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.Linq" />
......@@ -37,5 +39,9 @@
</ItemGroup>
<ItemGroup>
<None Update="NHibernate\*.xml" CopyToOutputDirectory="Always" />
<Compile Update="Benchmarks.*.cs" DependentUpon="Benchmarks.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="SourceLink.Create.GitHub" Version="2.1.2" />
</ItemGroup>
</Project>
......@@ -22,7 +22,7 @@
namespace Dapper.Tests.Performance
{
public partial class PerformanceTests
public class LegacyTests
{
private class Test
{
......@@ -81,7 +81,10 @@ public async Task RunAsync(int iterations)
foreach (var test in this.OrderBy(t => t.Watch.ElapsedMilliseconds))
{
Console.WriteLine(test.Name + " took " + test.Watch.ElapsedMilliseconds + "ms");
var ms = test.Watch.ElapsedMilliseconds.ToString();
Console.Write(ms);
Program.WriteColor("ms ".PadRight(8 - ms.Length), ConsoleColor.DarkGray);
Console.WriteLine(test.Name);
}
}
}
......@@ -114,6 +117,8 @@ public async Task RunAsync(int iterations)
{
using (var connection = GetOpenConnection())
{
#pragma warning disable IDE0017 // Simplify object initialization
#pragma warning disable RCS1121 // Use [] instead of calling 'First'.
var tests = new Tests();
// Linq2SQL
......@@ -252,35 +257,37 @@ public async Task RunAsync(int iterations)
}, "Belgrade Sql Client");
//Susanoo
var susanooDb = new DatabaseManager(connection);
var susanooPreDefinedCommand =
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<Post>()
.Realize();
var susanooDynamicPreDefinedCommand =
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<dynamic>()
.Realize();
tests.Add(Id =>
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<Post>()
.Realize()
.Execute(susanooDb, new { Id }).First(), "Susanoo: Mapping Cache Retrieval");
tests.Add(Id =>
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<dynamic>()
.Realize()
.Execute(susanooDb, new { Id }).First(), "Susanoo: Dynamic Mapping Cache Retrieval");
tests.Add(Id => susanooDynamicPreDefinedCommand
.Execute(susanooDb, new { Id }).First(), "Susanoo: Dynamic Mapping Static");
tests.Add(Id => susanooPreDefinedCommand
.Execute(susanooDb, new { Id }).First(), "Susanoo: Mapping Static");
Try(() => {
var susanooDb = new DatabaseManager(connection);
var susanooPreDefinedCommand =
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<Post>()
.Realize();
var susanooDynamicPreDefinedCommand =
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<dynamic>()
.Realize();
tests.Add(Id =>
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<Post>()
.Realize()
.Execute(susanooDb, new { Id }).First(), "Susanoo: Mapping Cache Retrieval");
tests.Add(Id =>
CommandManager.Instance.DefineCommand("SELECT * FROM Posts WHERE Id = @Id", CommandType.Text)
.DefineResults<dynamic>()
.Realize()
.Execute(susanooDb, new { Id }).First(), "Susanoo: Dynamic Mapping Cache Retrieval");
tests.Add(Id => susanooDynamicPreDefinedCommand
.Execute(susanooDb, new { Id }).First(), "Susanoo: Dynamic Mapping Static");
tests.Add(Id => susanooPreDefinedCommand
.Execute(susanooDb, new { Id }).First(), "Susanoo: Mapping Static");
}, "Susanoo");
//ServiceStack's OrmLite:
Try(() =>
......@@ -291,58 +298,44 @@ public async Task RunAsync(int iterations)
}, "ServiceStack.OrmLite");
// Hand Coded
var postCommand = new SqlCommand()
{
Connection = connection,
CommandText = @"select Id, [Text], [CreationDate], LastChangeDate,
Try(() => {
var 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"
};
var idParam = postCommand.Parameters.Add("@Id", SqlDbType.Int);
tests.Add(id =>
{
idParam.Value = id;
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);
}
}, "Hand Coded");
};
var idParam = postCommand.Parameters.Add("@Id", SqlDbType.Int);
// Subsonic isn't maintained anymore - doesn't import correctly
//Try(() =>
// {
// // Subsonic ActiveRecord
// tests.Add(id => 3SubSonic.Post.SingleOrDefault(x => x.Id == id), "SubSonic ActiveRecord.SingleOrDefault");
tests.Add(id =>
{
idParam.Value = id;
// // Subsonic coding horror
// SubSonic.tempdbDB db = new SubSonic.tempdbDB();
// tests.Add(id => new SubSonic.Query.CodingHorror(db.Provider, "select * from Posts where Id = @0", id).ExecuteTypedList<Post>(), "SubSonic Coding Horror");
//}, "Subsonic");
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);
//// BLToolkit - doesn't import correctly in the new .csproj world
//var db1 = new DbManager(GetOpenConnection());
//tests.Add(id => db1.SetCommand("select * from Posts where Id = @id", db1.Parameter("id", id)).ExecuteList<Post>(), "BLToolkit");
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);
}
}, "Hand Coded");
#if !COREFX
var table = new DataTable
{
Columns =
var table = new DataTable
{
Columns =
{
{"Id", typeof (int)},
{"Text", typeof (string)},
......@@ -358,22 +351,41 @@ public async Task RunAsync(int iterations)
{"Counter8", typeof (int)},
{"Counter9", typeof (int)},
}
};
tests.Add(id =>
{
idParam.Value = id;
object[] values = new object[13];
using (var reader = postCommand.ExecuteReader())
};
tests.Add(id =>
{
reader.Read();
reader.GetValues(values);
table.Rows.Add(values);
}
}, "DataTable via IDataReader.GetValues");
idParam.Value = id;
object[] values = new object[13];
using (var reader = postCommand.ExecuteReader())
{
reader.Read();
reader.GetValues(values);
table.Rows.Add(values);
}
}, "DataTable via IDataReader.GetValues");
#endif
}, "Hand Coded");
// Subsonic isn't maintained anymore - doesn't import correctly
//Try(() =>
// {
// // Subsonic ActiveRecord
// tests.Add(id => 3SubSonic.Post.SingleOrDefault(x => x.Id == id), "SubSonic ActiveRecord.SingleOrDefault");
// // Subsonic coding horror
// SubSonic.tempdbDB db = new SubSonic.tempdbDB();
// tests.Add(id => new SubSonic.Query.CodingHorror(db.Provider, "select * from Posts where Id = @0", id).ExecuteTypedList<Post>(), "SubSonic Coding Horror");
//}, "Subsonic");
//// BLToolkit - doesn't import correctly in the new .csproj world
//var db1 = new DbManager(GetOpenConnection());
//tests.Add(id => db1.SetCommand("select * from Posts where Id = @id", db1.Parameter("id", id)).ExecuteList<Post>(), "BLToolkit");
Console.WriteLine();
Console.WriteLine("Running...");
await tests.RunAsync(iterations).ConfigureAwait(false);
#pragma warning restore RCS1121 // Use [] instead of calling 'First'.
#pragma warning restore IDE0017 // Simplify object initialization
}
}
}
......
using System;
using System.Threading.Tasks;
using BenchmarkDotNet.Running;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using static System.Console;
namespace Dapper.Tests.Performance
{
// Note: VSTest injects an entry point in .NET Core land...so we have to split this out into
// a separate project...so here we are.
// See https://github.com/Microsoft/vstest/issues/636 for details
public static class Program
{
public static void Main()
public static void Main(string[] args)
{
#if DEBUG
var fg = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Warning: DEBUG configuration; performance may be impacted");
Console.ForegroundColor = fg;
Console.WriteLine();
WriteLineColor("Warning: DEBUG configuration; performance may be impacted!", ConsoleColor.Red);
WriteLine();
#endif
Console.WriteLine("Using ConnectionString: " + PerformanceTests.ConnectionString);
WriteLine("Welcome to Dapper's ORM performance benchmark suite, based on BenchmarkDotNet.");
Write(" If you find a problem, please report it at: ");
WriteLineColor("https://github.com/StackExchange/Dapper", ConsoleColor.Blue);
WriteLine(" Or if you're up to it, please submit a pull request! We welcome new additions.");
WriteLine();
if (args.Length == 0)
{
WriteLine("Optional arguments:");
WriteColor(" --all", ConsoleColor.Blue);
WriteLine(": run all benchmarks");
WriteColor(" --legacy", ConsoleColor.Blue);
WriteLine(": run the legacy benchmark suite/format", ConsoleColor.Gray);
WriteLine();
}
WriteLine("Using ConnectionString: " + BenchmarkBase.ConnectionString);
EnsureDBSetup();
RunPerformanceTestsAsync().GetAwaiter().GetResult();
WriteLine("Database setup complete.");
if (args.Any(a => a == "--all"))
{
WriteLine("Iterations: " + BenchmarkBase.Iterations);
var benchmarks = new List<Benchmark>();
var benchTypes = Assembly.GetEntryAssembly().DefinedTypes.Where(t => t.IsSubclassOf(typeof(BenchmarkBase)));
WriteLineColor("Running full benchmarks suite", ConsoleColor.Green);
foreach (var b in benchTypes)
{
benchmarks.AddRange(BenchmarkConverter.TypeToBenchmarks(b));
}
BenchmarkRunner.Run(benchmarks.ToArray(), null);
}
else if (args.Any(a => a == "--legacy"))
{
var test = new LegacyTests();
const int iterations = 500;
WriteLineColor($"Running legacy benchmarks: {iterations} iterations that load up a Post entity.", ConsoleColor.Green);
test.RunAsync(iterations).GetAwaiter().GetResult();
WriteLine();
WriteLineColor("Run complete.", ConsoleColor.Green);
}
else
{
WriteLine("Iterations: " + BenchmarkBase.Iterations);
BenchmarkSwitcher.FromAssembly(typeof(Program).GetTypeInfo().Assembly).Run(args);
}
}
private static void EnsureDBSetup()
{
using (var cnn = PerformanceTests.GetOpenConnection())
using (var cnn = new SqlConnection(BenchmarkBase.ConnectionString))
{
cnn.Open();
var cmd = cnn.CreateCommand();
cmd.CommandText = @"
if (OBJECT_ID('Posts') is null)
begin
create table Posts
If (Object_Id('Posts') Is Null)
Begin
Create Table Posts
(
Id int identity primary key,
[Text] varchar(max) not null,
......@@ -46,38 +87,36 @@ private static void EnsureDBSetup()
Counter7 int,
Counter8 int,
Counter9 int
)
);
set nocount on
declare @i int
declare @c int
declare @id int
Set NoCount On;
Declare @i int = 0;
set @i = 0
while @i <= 5001
begin
insert Posts ([Text],CreationDate, LastChangeDate) values (replicate('x', 2000), GETDATE(), GETDATE())
set @id = @@IDENTITY
set @i = @i + 1
end
end
While @i <= 5001
Begin
Insert Posts ([Text],CreationDate, LastChangeDate) values (replicate('x', 2000), GETDATE(), GETDATE());
Set @i = @i + 1;
End
End
";
cmd.Connection = cnn;
cmd.ExecuteNonQuery();
}
}
private static async Task RunPerformanceTestsAsync()
public static void WriteLineColor(string message, ConsoleColor color)
{
var orig = ForegroundColor;
ForegroundColor = color;
WriteLine(message);
ForegroundColor = orig;
}
public static void WriteColor(string message, ConsoleColor color)
{
var test = new PerformanceTests();
const int iterations = 500;
Console.WriteLine("Running {0} iterations that load up a post entity", iterations);
await test.RunAsync(iterations).ConfigureAwait(false);
var orig = ForegroundColor;
ForegroundColor = color;
Write(message);
ForegroundColor = orig;
}
}
}
......@@ -5,7 +5,7 @@ namespace Dapper.Tests.Performance.Soma
{
internal class SomaConfig : MsSqlConfig
{
public override string ConnectionString => PerformanceTests.ConnectionString;
public override string ConnectionString => BenchmarkBase.ConnectionString;
public override Action<PreparedStatement> Logger => noOp;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册