Skip to content

Commit 9eb14c5

Browse files
Added benchmark
1 parent cc9e7f2 commit 9eb14c5

5 files changed

Lines changed: 112 additions & 12 deletions

File tree

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
using Microsoft.Data.Sqlite;
1111
using Microsoft.EntityFrameworkCore;
1212

13+
using MySqlConnector;
14+
1315
using Npgsql;
1416

1517
using PhenX.EntityFrameworkCore.BulkInsert.Extensions;
@@ -87,6 +89,11 @@ public void RawInsert()
8789
// Use BeginBinaryImport for PostgreSQL
8890
RawInsertPostgreSql();
8991
}
92+
else if (DbContext.Database.ProviderName!.Contains("MySql", StringComparison.InvariantCultureIgnoreCase))
93+
{
94+
// Use MySqlBulkCopy for PostgreSQL
95+
RawInsertMySql();
96+
}
9097
}
9198

9299
[Benchmark]
@@ -264,4 +271,59 @@ private void RawInsertSqlServer()
264271
bulkCopy.WriteToServer(dataTable);
265272
}
266273
}
274+
275+
private void RawInsertMySql()
276+
{
277+
var connection = (MySqlConnection)DbContext.Database.GetDbConnection();
278+
if (connection.State != ConnectionState.Open)
279+
{
280+
connection.Open();
281+
}
282+
283+
var bulkCopy = new MySqlBulkCopy(connection);
284+
285+
bulkCopy.DestinationTableName = nameof(TestEntity);
286+
bulkCopy.BulkCopyTimeout = 60;
287+
288+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name"));
289+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price"));
290+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier"));
291+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt"));
292+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt"));
293+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue"));
294+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(6, "NumericEnumValue"));
295+
296+
var dataTable = new DataTable();
297+
dataTable.Columns.Add("Name", typeof(string));
298+
dataTable.Columns.Add("Price", typeof(decimal));
299+
dataTable.Columns.Add("Identifier", typeof(Guid));
300+
dataTable.Columns.Add("CreatedAt", typeof(DateTime));
301+
dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset));
302+
dataTable.Columns.Add("StringEnumValue", typeof(string));
303+
dataTable.Columns.Add("NumericEnumValue", typeof(int));
304+
305+
foreach (var entity in data)
306+
{
307+
var row = dataTable.NewRow();
308+
row["Name"] = entity.Name;
309+
row["Price"] = entity.Price;
310+
row["Identifier"] = entity.Identifier;
311+
row["CreatedAt"] = entity.CreatedAt;
312+
row["UpdatedAt"] = entity.UpdatedAt;
313+
row["StringEnumValue"] = entity.StringEnumValue.ToString();
314+
row["NumericEnumValue"] = (int)entity.NumericEnumValue;
315+
dataTable.Rows.Add(row);
316+
317+
if (dataTable.Rows.Count >= 50_000)
318+
{
319+
bulkCopy.WriteToServer(dataTable);
320+
dataTable.Clear();
321+
}
322+
}
323+
324+
if (dataTable.Rows.Count > 0)
325+
{
326+
bulkCopy.WriteToServer(dataTable);
327+
}
328+
}
267329
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using BenchmarkDotNet.Attributes;
2+
using BenchmarkDotNet.Engines;
3+
4+
using DotNet.Testcontainers.Containers;
5+
6+
using Microsoft.EntityFrameworkCore;
7+
8+
using PhenX.EntityFrameworkCore.BulkInsert.MySql;
9+
10+
using Testcontainers.MySql;
11+
12+
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
13+
14+
[MinColumn, MaxColumn, BaselineColumn]
15+
[MemoryDiagnoser]
16+
[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)]
17+
public class LibComparatorMySql : LibComparator
18+
{
19+
protected override void ConfigureDbContext()
20+
{
21+
var connectionString = GetConnectionString() + ";AllowLoadLocalInfile=true;";
22+
23+
DbContext = new TestDbContext(p => p
24+
.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
25+
.UseBulkInsertMySql()
26+
);
27+
}
28+
29+
protected override IDatabaseContainer? GetDbContainer()
30+
{
31+
return new MySqlBuilder()
32+
.WithCommand("--log-bin-trust-function-creators=1", "--local-infile=1")
33+
.Build();
34+
}
35+
}

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,27 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="BenchmarkDotNet" Version="0.14.0"/>
11-
<PackageReference Include="Testcontainers.PostgreSql" Version="4.4.0"/>
12-
<PackageReference Include="Testcontainers.MsSql" Version="4.4.0"/>
10+
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
11+
<PackageReference Include="Testcontainers.PostgreSql" Version="4.4.0" />
12+
<PackageReference Include="Testcontainers.MsSql" Version="4.4.0" />
13+
<PackageReference Include="Testcontainers.MySql" Version="4.4.0" />
1314
</ItemGroup>
1415

1516
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
16-
<PackageReference Include="EFCore.BulkExtensions" Version="8.1.3"/>
17-
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="8.103.8.1"/>
17+
<PackageReference Include="EFCore.BulkExtensions" Version="8.1.3" />
18+
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="8.103.8.1" />
1819
</ItemGroup>
1920

2021
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
21-
<PackageReference Include="EFCore.BulkExtensions" Version="9.0.1"/>
22-
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="9.103.8.1"/>
22+
<PackageReference Include="EFCore.BulkExtensions" Version="9.0.1" />
23+
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="9.103.8.1" />
2324
</ItemGroup>
2425

2526
<ItemGroup>
26-
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.PostgreSql\PhenX.EntityFrameworkCore.BulkInsert.PostgreSql.csproj"/>
27-
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.Sqlite\PhenX.EntityFrameworkCore.BulkInsert.Sqlite.csproj"/>
28-
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.SqlServer\PhenX.EntityFrameworkCore.BulkInsert.SqlServer.csproj"/>
27+
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.MySql\PhenX.EntityFrameworkCore.BulkInsert.MySql.csproj" />
28+
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.PostgreSql\PhenX.EntityFrameworkCore.BulkInsert.PostgreSql.csproj" />
29+
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.Sqlite\PhenX.EntityFrameworkCore.BulkInsert.Sqlite.csproj" />
30+
<ProjectReference Include="..\..\src\PhenX.EntityFrameworkCore.BulkInsert.SqlServer\PhenX.EntityFrameworkCore.BulkInsert.SqlServer.csproj" />
2931
</ItemGroup>
3032

3133
</Project>

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using BenchmarkDotNet.Configs;
1+
using BenchmarkDotNet.Configs;
22
using BenchmarkDotNet.Running;
33

44
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
@@ -11,6 +11,7 @@ public static void Main(string[] args)
1111
.Create(DefaultConfig.Instance)
1212
.WithOptions(ConfigOptions.DisableOptimizationsValidator);
1313

14+
BenchmarkRunner.Run<LibComparatorMySql>(config);
1415
BenchmarkRunner.Run<LibComparatorPostgreSql>(config);
1516
BenchmarkRunner.Run<LibComparatorSqlServer>(config);
1617
BenchmarkRunner.Run<LibComparatorSqlite>(config);

tests/PhenX.EntityFrameworkCore.BulkInsert.Tests/PhenX.EntityFrameworkCore.BulkInsert.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
</PackageReference>
1616
<PackageReference Include="Meziantou.Xunit.ParallelTestFramework" Version="2.3.0" />
1717
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
18-
<PackageReference Include="Testcontainers.MySql" Version="4.4.0" />
1918
<PackageReference Include="xunit" Version="2.9.3" />
2019
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
2120
<PrivateAssets>all</PrivateAssets>
@@ -25,6 +24,7 @@
2524
<PackageReference Include="Testcontainers" Version="4.4.0" />
2625
<PackageReference Include="Testcontainers.PostgreSql" Version="4.4.0" />
2726
<PackageReference Include="Testcontainers.MsSql" Version="4.4.0" />
27+
<PackageReference Include="Testcontainers.MySql" Version="4.4.0" />
2828
</ItemGroup>
2929

3030
<ItemGroup>

0 commit comments

Comments
 (0)