|
@@ -4,12 +4,12 @@ using System.Data;
|
|
using System.Data.Common;
|
|
using System.Data.Common;
|
|
using System.Text;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Threading.Tasks;
|
|
-
|
|
|
|
|
|
+using System.Collections.Concurrent;
|
|
namespace Benchmarks
|
|
namespace Benchmarks
|
|
{
|
|
{
|
|
public class RawDb
|
|
public class RawDb
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+
|
|
private readonly ConcurrentRandom _random;
|
|
private readonly ConcurrentRandom _random;
|
|
|
|
|
|
private readonly DbProviderFactory _dbProviderFactory;
|
|
private readonly DbProviderFactory _dbProviderFactory;
|
|
@@ -21,20 +21,83 @@ namespace Benchmarks
|
|
_random = random;
|
|
_random = random;
|
|
_dbProviderFactory = dbProviderFactory;
|
|
_dbProviderFactory = dbProviderFactory;
|
|
_connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
|
|
_connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
|
|
|
|
+ //_connectionString = "Server=192.168.2.19;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < 256; i++)
|
|
|
|
+ {
|
|
|
|
+ DbConnection conn = dbProviderFactory.CreateConnection();
|
|
|
|
+ conn.ConnectionString = _connectionString;
|
|
|
|
+ RawDbConnection rawDbConnection = new RawDbConnection(conn, this);
|
|
|
|
+ mPool.Push(rawDbConnection);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- public async Task<World> LoadSingleQueryRow()
|
|
|
|
|
|
+
|
|
|
|
+ private ConcurrentStack<RawDbConnection> mPool = new ConcurrentStack<RawDbConnection>();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private RawDbConnection Pop()
|
|
|
|
+ {
|
|
|
|
+ if (mPool.TryPop(out RawDbConnection conn))
|
|
|
|
+ return conn;
|
|
|
|
+ else
|
|
|
|
+ throw new Exception("get raw db connection error!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void Push(RawDbConnection conn)
|
|
|
|
+ {
|
|
|
|
+ mPool.Push(conn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ class RawDbConnection : IDisposable
|
|
{
|
|
{
|
|
- using (var db = _dbProviderFactory.CreateConnection())
|
|
|
|
|
|
+ public RawDbConnection(DbConnection connection, RawDb rawdb)
|
|
{
|
|
{
|
|
- db.ConnectionString = _connectionString;
|
|
|
|
- await db.OpenAsync();
|
|
|
|
|
|
+ Connection = connection;
|
|
|
|
+ Connection.Open();
|
|
|
|
+
|
|
|
|
+ var cmd = connection.CreateCommand();
|
|
|
|
+ cmd.CommandText = "SELECT id, randomnumber FROM world WHERE id = @Id";
|
|
|
|
+ var id = cmd.CreateParameter();
|
|
|
|
+ id.ParameterName = "@Id";
|
|
|
|
+ id.DbType = DbType.Int32;
|
|
|
|
+ id.Value = 0;
|
|
|
|
+ cmd.Parameters.Add(id);
|
|
|
|
+ ReadCommand = cmd;
|
|
|
|
+
|
|
|
|
+ cmd = connection.CreateCommand();
|
|
|
|
+ cmd.CommandText = "SELECT id, message FROM fortune";
|
|
|
|
+ FortuneCommand = cmd;
|
|
|
|
+
|
|
|
|
+ DbHandler = rawdb;
|
|
|
|
|
|
- using (var cmd = CreateReadCommand(db))
|
|
|
|
- {
|
|
|
|
- return await ReadSingleRow(db, cmd);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ public DbConnection Connection { get; private set; }
|
|
|
|
+
|
|
|
|
+ public DbCommand ReadCommand { get; private set; }
|
|
|
|
+
|
|
|
|
+ public DbCommand FortuneCommand { get; private set; }
|
|
|
|
+
|
|
|
|
+ public RawDb DbHandler { get; private set; }
|
|
|
|
+
|
|
|
|
+ public void Dispose()
|
|
|
|
+ {
|
|
|
|
+ DbHandler.Push(this);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public async Task<World> LoadSingleQueryRow()
|
|
|
|
+ {
|
|
|
|
+ using (var conn = Pop())
|
|
|
|
+ {
|
|
|
|
+ var cmd = conn.ReadCommand;
|
|
|
|
+ cmd.Parameters[0].Value = _random.Next(1, 10001);
|
|
|
|
+ return await ReadSingleRow(conn.Connection, cmd);
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
async Task<World> ReadSingleRow(DbConnection connection, DbCommand cmd)
|
|
async Task<World> ReadSingleRow(DbConnection connection, DbCommand cmd)
|
|
@@ -51,58 +114,36 @@ namespace Benchmarks
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- DbCommand CreateReadCommand(DbConnection connection)
|
|
|
|
- {
|
|
|
|
- var cmd = connection.CreateCommand();
|
|
|
|
- cmd.CommandText = "SELECT id, randomnumber FROM world WHERE id = @Id";
|
|
|
|
- var id = cmd.CreateParameter();
|
|
|
|
- id.ParameterName = "@Id";
|
|
|
|
- id.DbType = DbType.Int32;
|
|
|
|
- id.Value = _random.Next(1, 10001);
|
|
|
|
- cmd.Parameters.Add(id);
|
|
|
|
- return cmd;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
|
|
public async Task<World[]> LoadMultipleQueriesRows(int count)
|
|
public async Task<World[]> LoadMultipleQueriesRows(int count)
|
|
{
|
|
{
|
|
- using (var db = _dbProviderFactory.CreateConnection())
|
|
|
|
|
|
+ using (var conn = Pop())
|
|
{
|
|
{
|
|
- db.ConnectionString = _connectionString;
|
|
|
|
- await db.OpenAsync();
|
|
|
|
- return await LoadMultipleRows(count, db);
|
|
|
|
|
|
+ var cmd = conn.ReadCommand;
|
|
|
|
+ cmd.Parameters[0].Value = _random.Next(1, 10001);
|
|
|
|
+ return await LoadMultipleRows(count, conn.Connection, conn.ReadCommand);
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- private async Task<World[]> LoadMultipleRows(int count, DbConnection db)
|
|
|
|
|
|
+ private async Task<World[]> LoadMultipleRows(int count, DbConnection db, DbCommand cmd)
|
|
{
|
|
{
|
|
- using (var cmd = CreateReadCommand(db))
|
|
|
|
|
|
+ cmd.Parameters[0].Value = _random.Next(1, 10001);
|
|
|
|
+ var result = new World[count];
|
|
|
|
+ for (int i = 0; i < result.Length; i++)
|
|
{
|
|
{
|
|
- cmd.Parameters["@Id"].Value = _random.Next(1, 10001);
|
|
|
|
-
|
|
|
|
- var result = new World[count];
|
|
|
|
- for (int i = 0; i < result.Length; i++)
|
|
|
|
- {
|
|
|
|
- result[i] = await ReadSingleRow(db, cmd);
|
|
|
|
- cmd.Parameters["@Id"].Value = _random.Next(1, 10001);
|
|
|
|
- }
|
|
|
|
- return result;
|
|
|
|
|
|
+ result[i] = await ReadSingleRow(db, cmd);
|
|
|
|
+ cmd.Parameters[0].Value = _random.Next(1, 10001);
|
|
}
|
|
}
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<List<Fortune>> LoadFortunesRows()
|
|
public async Task<List<Fortune>> LoadFortunesRows()
|
|
{
|
|
{
|
|
var result = new List<Fortune>();
|
|
var result = new List<Fortune>();
|
|
-
|
|
|
|
- using (var db = _dbProviderFactory.CreateConnection())
|
|
|
|
- using (var cmd = db.CreateCommand())
|
|
|
|
|
|
+ using (var conn = Pop())
|
|
{
|
|
{
|
|
- cmd.CommandText = "SELECT id, message FROM fortune";
|
|
|
|
-
|
|
|
|
- db.ConnectionString = _connectionString;
|
|
|
|
- await db.OpenAsync();
|
|
|
|
- using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.CloseConnection))
|
|
|
|
|
|
+ var cmd = conn.FortuneCommand;
|
|
|
|
+ using (var rdr = await cmd.ExecuteReaderAsync(CommandBehavior.Default))
|
|
{
|
|
{
|
|
while (await rdr.ReadAsync())
|
|
while (await rdr.ReadAsync())
|
|
{
|
|
{
|
|
@@ -114,7 +155,6 @@ namespace Benchmarks
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
result.Add(new Fortune { Message = "Additional fortune added at request time." });
|
|
result.Add(new Fortune { Message = "Additional fortune added at request time." });
|
|
result.Sort();
|
|
result.Sort();
|
|
return result;
|
|
return result;
|