From 4e542175a70e74ac599c6293df7e3194654dfea8 Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Wed, 21 May 2025 21:54:37 +0200 Subject: [PATCH 1/6] Add Linq2DB to benchmarks --- README.md | 2 +- .../LibComparator.RawInsert.cs | 150 ++++++++++++++++ .../LibComparator.cs | 166 ++---------------- .../LibComparatorPostgreSql.cs | 4 +- .../LibComparatorSqlServer.cs | 3 + .../LibComparatorSqlite.cs | 3 + ...yFrameworkCore.BulkInsert.Benchmark.csproj | 2 + 7 files changed, 177 insertions(+), 153 deletions(-) create mode 100644 tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs diff --git a/README.md b/README.md index 227a927..6463a7d 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Legend : * `RawInsert`: no library, using the native provider API (SqlBulkCopy for SQL Server, BeginBinaryImport for PostgreSQL, raw inserts for SQLite) * `Z_EntityFramework_Extensions_EFCore`: https://entityframework-extensions.net/bulk-extensions * `EFCore_BulkExtensions`: https://github.com/borisdj/EFCore.BulkExtensions - * `EFCore_SaveChanges`: EF Core SaveChanges classic method + * `Linq2Db`: https://github.com/linq2db/linq2db SQL Server results with 500 000 rows : diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs new file mode 100644 index 0000000..1b60468 --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs @@ -0,0 +1,150 @@ +using System.Data; + +using Microsoft.Data.SqlClient; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; + +using Npgsql; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; + +public abstract partial class LibComparator +{ + private void RawInsertPostgreSql() + { + using var connection = (NpgsqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + const string copyCommand = $""" + COPY "{nameof(TestEntity)}" ( + "Name", + "Price", + "Identifier", + "CreatedAt", + "UpdatedAt", + "StringEnumValue", + "NumericEnumValue" + ) FROM STDIN (FORMAT BINARY) + """; + + using var writer = connection.BeginBinaryImport(copyCommand); + foreach (var entity in data) + { + writer.StartRow(); + writer.Write(entity.Name); + writer.Write(entity.Price); + writer.Write(entity.Identifier); + writer.Write(entity.CreatedAt); + writer.Write(entity.UpdatedAt); + writer.Write(entity.StringEnumValue.ToString()); + writer.Write((int)entity.NumericEnumValue); + } + + writer.Complete(); + } + + private void RawInsertSqlite() + { + var connection = (SqliteConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + using var transaction = connection.BeginTransaction(); + using var command = connection.CreateCommand(); + command.CommandText = $""" + INSERT INTO "{nameof(TestEntity)}" ( + "Name", + "Price", + "Identifier", + "CreatedAt", + "UpdatedAt", + "StringEnumValue", + "NumericEnumValue" + ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue) + """; + + command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); + command.Parameters.Add(new SqliteParameter("@Price", DbType.Decimal)); + command.Parameters.Add(new SqliteParameter("@Identifier", DbType.Guid)); + command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); + command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); + command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String)); + command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); + + foreach (var entity in data) + { + command.Parameters["@Name"].Value = entity.Name; + command.Parameters["@Price"].Value = entity.Price; + command.Parameters["@Identifier"].Value = entity.Identifier; + command.Parameters["@CreatedAt"].Value = entity.CreatedAt; + command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; + command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString(); + command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; + + command.ExecuteNonQuery(); + } + + transaction.Commit(); + } + + private void RawInsertSqlServer() + { + var connection = (SqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + using var bulkCopy = new SqlBulkCopy(connection); + + bulkCopy.DestinationTableName = nameof(TestEntity); + bulkCopy.BatchSize = 50_000; + bulkCopy.BulkCopyTimeout = 60; + + bulkCopy.ColumnMappings.Add("Name", "Name"); + bulkCopy.ColumnMappings.Add("Price", "Price"); + bulkCopy.ColumnMappings.Add("Identifier", "Identifier"); + bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); + bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); + bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue"); + bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); + + var dataTable = new DataTable(); + dataTable.Columns.Add("Name", typeof(string)); + dataTable.Columns.Add("Price", typeof(decimal)); + dataTable.Columns.Add("Identifier", typeof(Guid)); + dataTable.Columns.Add("CreatedAt", typeof(DateTime)); + dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); + dataTable.Columns.Add("StringEnumValue", typeof(string)); + dataTable.Columns.Add("NumericEnumValue", typeof(int)); + + foreach (var entity in data) + { + var row = dataTable.NewRow(); + row["Name"] = entity.Name; + row["Price"] = entity.Price; + row["Identifier"] = entity.Identifier; + row["CreatedAt"] = entity.CreatedAt; + row["UpdatedAt"] = entity.UpdatedAt; + row["StringEnumValue"] = entity.StringEnumValue.ToString(); + row["NumericEnumValue"] = (int)entity.NumericEnumValue; + dataTable.Rows.Add(row); + + if (dataTable.Rows.Count >= 50_000) + { + bulkCopy.WriteToServer(dataTable); + dataTable.Clear(); + } + } + + if (dataTable.Rows.Count > 0) + { + bulkCopy.WriteToServer(dataTable); + } + } +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs index c868c4e..48fcd2b 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs @@ -1,22 +1,16 @@ -using System.Data; - using BenchmarkDotNet.Attributes; using DotNet.Testcontainers.Containers; using EFCore.BulkExtensions; -using Microsoft.Data.SqlClient; -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; - -using Npgsql; +using LinqToDB.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.Extensions; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -public abstract class LibComparator +public abstract partial class LibComparator { [Params(500_000/*, 1_000_000/*, 10_000_000*/)] public int N; @@ -44,6 +38,7 @@ protected LibComparator() { DbContainer = GetDbContainer(); DbContainer?.StartAsync().GetAwaiter().GetResult(); + LinqToDBForEFTools.Initialize(); } protected abstract void ConfigureDbContext(); @@ -89,6 +84,12 @@ public void RawInsert() } } + [Benchmark] + public async Task Linq2Db() + { + await DbContext.BulkCopyAsync(data); + } + [Benchmark] public async Task Z_EntityFramework_Extensions_EFCore() { @@ -121,147 +122,10 @@ await DbContext.BulkInsertAsync(data, options => // }); // } - [Benchmark] - public async Task EFCore_SaveChanges() - { - DbContext.AddRange(data); - await DbContext.SaveChangesAsync(); - } - - private void RawInsertPostgreSql() - { - using var connection = (NpgsqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - const string copyCommand = $""" - COPY "{nameof(TestEntity)}" ( - "Name", - "Price", - "Identifier", - "CreatedAt", - "UpdatedAt", - "StringEnumValue", - "NumericEnumValue" - ) FROM STDIN (FORMAT BINARY) - """; - - using var writer = connection.BeginBinaryImport(copyCommand); - foreach (var entity in data) - { - writer.StartRow(); - writer.Write(entity.Name); - writer.Write(entity.Price); - writer.Write(entity.Identifier); - writer.Write(entity.CreatedAt); - writer.Write(entity.UpdatedAt); - writer.Write(entity.StringEnumValue.ToString()); - writer.Write((int)entity.NumericEnumValue); - } - - writer.Complete(); - } - - private void RawInsertSqlite() - { - var connection = (SqliteConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - using var transaction = connection.BeginTransaction(); - using var command = connection.CreateCommand(); - command.CommandText = $""" - INSERT INTO "{nameof(TestEntity)}" ( - "Name", - "Price", - "Identifier", - "CreatedAt", - "UpdatedAt", - "StringEnumValue", - "NumericEnumValue" - ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue) - """; - - command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); - command.Parameters.Add(new SqliteParameter("@Price", DbType.Decimal)); - command.Parameters.Add(new SqliteParameter("@Identifier", DbType.Guid)); - command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); - command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); - command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String)); - command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); - - foreach (var entity in data) - { - command.Parameters["@Name"].Value = entity.Name; - command.Parameters["@Price"].Value = entity.Price; - command.Parameters["@Identifier"].Value = entity.Identifier; - command.Parameters["@CreatedAt"].Value = entity.CreatedAt; - command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; - command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString(); - command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; - - command.ExecuteNonQuery(); - } - - transaction.Commit(); - } - - private void RawInsertSqlServer() - { - var connection = (SqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - using var bulkCopy = new SqlBulkCopy(connection); - - bulkCopy.DestinationTableName = nameof(TestEntity); - bulkCopy.BatchSize = 50_000; - bulkCopy.BulkCopyTimeout = 60; - - bulkCopy.ColumnMappings.Add("Name", "Name"); - bulkCopy.ColumnMappings.Add("Price", "Price"); - bulkCopy.ColumnMappings.Add("Identifier", "Identifier"); - bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); - bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); - bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue"); - bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); - - var dataTable = new DataTable(); - dataTable.Columns.Add("Name", typeof(string)); - dataTable.Columns.Add("Price", typeof(decimal)); - dataTable.Columns.Add("Identifier", typeof(Guid)); - dataTable.Columns.Add("CreatedAt", typeof(DateTime)); - dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); - dataTable.Columns.Add("NumericEnumValue", typeof(int)); - - foreach (var entity in data) - { - var row = dataTable.NewRow(); - row["Name"] = entity.Name; - row["Price"] = entity.Price; - row["Identifier"] = entity.Identifier; - row["CreatedAt"] = entity.CreatedAt; - row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); - row["NumericEnumValue"] = (int)entity.NumericEnumValue; - dataTable.Rows.Add(row); - - if (dataTable.Rows.Count >= 50_000) - { - bulkCopy.WriteToServer(dataTable); - dataTable.Clear(); - } - } - - if (dataTable.Rows.Count > 0) - { - bulkCopy.WriteToServer(dataTable); - } - } + // [Benchmark] + // public async Task EFCore_SaveChanges() + // { + // DbContext.AddRange(data); + // await DbContext.SaveChangesAsync(); + // } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs index 0228703..a803e02 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs @@ -3,6 +3,8 @@ using DotNet.Testcontainers.Containers; +using LinqToDB.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.PostgreSql; @@ -11,7 +13,6 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -[MinColumn, MaxColumn, BaselineColumn] [MemoryDiagnoser] [SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorPostgreSql : LibComparator @@ -23,6 +24,7 @@ protected override void ConfigureDbContext() DbContext = new TestDbContext(p => p .UseNpgsql(connectionString) .UseBulkInsertPostgreSql() + .UseLinqToDB() ); } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs index ad7e843..b0b027d 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs @@ -3,6 +3,8 @@ using DotNet.Testcontainers.Containers; +using LinqToDB.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.Sqlite; @@ -24,6 +26,7 @@ protected override void ConfigureDbContext() DbContext = new TestDbContext(p => p .UseSqlServer(connectionString) .UseBulkInsertSqlServer() + .UseLinqToDB() ); } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs index 3541adc..cc12c13 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs @@ -3,6 +3,8 @@ using DotNet.Testcontainers.Containers; +using LinqToDB.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.Sqlite; @@ -21,6 +23,7 @@ protected override void ConfigureDbContext() DbContext = new TestDbContext(p => p .UseSqlite(connectionString) .UseBulkInsertSqlite() + .UseLinqToDB() ); } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj index 0396901..d579887 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj @@ -15,11 +15,13 @@ + + From 0ba0264b24eaa8b68b15f084e3fc274b964abf6c Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Fri, 23 May 2025 16:16:29 +0200 Subject: [PATCH 2/6] Do not insert NumericEnumValue because of linq2db not handling it right with provider specific import and simplify benchmark --- .../LibComparator.RawInsert.cs | 68 +++++++++++++--- .../LibComparator.cs | 81 +++---------------- .../LibComparatorMySql.cs | 6 -- .../LibComparatorPostgreSql.cs | 5 -- .../LibComparatorSqlServer.cs | 6 -- .../LibComparatorSqlite.cs | 6 -- .../TestEntity.cs | 8 -- 7 files changed, 69 insertions(+), 111 deletions(-) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs index 1b60468..1d5b602 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs @@ -4,6 +4,8 @@ using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using MySqlConnector; + using Npgsql; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; @@ -25,8 +27,7 @@ private void RawInsertPostgreSql() "Identifier", "CreatedAt", "UpdatedAt", - "StringEnumValue", - "NumericEnumValue" + "StringEnumValue" ) FROM STDIN (FORMAT BINARY) """; @@ -40,7 +41,6 @@ private void RawInsertPostgreSql() writer.Write(entity.CreatedAt); writer.Write(entity.UpdatedAt); writer.Write(entity.StringEnumValue.ToString()); - writer.Write((int)entity.NumericEnumValue); } writer.Complete(); @@ -63,9 +63,8 @@ private void RawInsertSqlite() "Identifier", "CreatedAt", "UpdatedAt", - "StringEnumValue", - "NumericEnumValue" - ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue) + "StringEnumValue" + ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue) """; command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); @@ -74,7 +73,6 @@ private void RawInsertSqlite() command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String)); - command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); foreach (var entity in data) { @@ -84,7 +82,6 @@ private void RawInsertSqlite() command.Parameters["@CreatedAt"].Value = entity.CreatedAt; command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString(); - command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; command.ExecuteNonQuery(); } @@ -112,7 +109,6 @@ private void RawInsertSqlServer() bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue"); - bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); var dataTable = new DataTable(); dataTable.Columns.Add("Name", typeof(string)); @@ -121,7 +117,6 @@ private void RawInsertSqlServer() dataTable.Columns.Add("CreatedAt", typeof(DateTime)); dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); dataTable.Columns.Add("StringEnumValue", typeof(string)); - dataTable.Columns.Add("NumericEnumValue", typeof(int)); foreach (var entity in data) { @@ -132,7 +127,58 @@ private void RawInsertSqlServer() row["CreatedAt"] = entity.CreatedAt; row["UpdatedAt"] = entity.UpdatedAt; row["StringEnumValue"] = entity.StringEnumValue.ToString(); - row["NumericEnumValue"] = (int)entity.NumericEnumValue; + dataTable.Rows.Add(row); + + if (dataTable.Rows.Count >= 50_000) + { + bulkCopy.WriteToServer(dataTable); + dataTable.Clear(); + } + } + + if (dataTable.Rows.Count > 0) + { + bulkCopy.WriteToServer(dataTable); + } + } + + private void RawInsertMySql() + { + var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + var bulkCopy = new MySqlBulkCopy(connection); + + bulkCopy.DestinationTableName = nameof(TestEntity); + bulkCopy.BulkCopyTimeout = 60; + + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue")); + + var dataTable = new DataTable(); + dataTable.Columns.Add("Name", typeof(string)); + dataTable.Columns.Add("Price", typeof(decimal)); + dataTable.Columns.Add("Identifier", typeof(Guid)); + dataTable.Columns.Add("CreatedAt", typeof(DateTime)); + dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); + dataTable.Columns.Add("StringEnumValue", typeof(string)); + + foreach (var entity in data) + { + var row = dataTable.NewRow(); + row["Name"] = entity.Name; + row["Price"] = entity.Price; + row["Identifier"] = entity.Identifier; + row["CreatedAt"] = entity.CreatedAt; + row["UpdatedAt"] = entity.UpdatedAt; + row["StringEnumValue"] = entity.StringEnumValue.ToString(); dataTable.Rows.Add(row); if (dataTable.Rows.Count >= 50_000) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs index 4e930c4..48c1e61 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs @@ -1,23 +1,19 @@ using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; using DotNet.Testcontainers.Containers; using EFCore.BulkExtensions; +using LinqToDB.Data; using LinqToDB.EntityFrameworkCore; -using Microsoft.Data.SqlClient; -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; - -using MySqlConnector; - -using Npgsql; - using PhenX.EntityFrameworkCore.BulkInsert.Extensions; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +[MemoryDiagnoser] +[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 5)] public abstract partial class LibComparator { [Params(500_000/*, 1_000_000/*, 10_000_000*/)] @@ -35,7 +31,6 @@ public void IterationSetup() Price = (decimal)(i * 0.1), Identifier = Guid.NewGuid(), StringEnumValue = (StringEnum)(i % 2), - NumericEnumValue = (NumericEnum)(i % 2), }).ToList(); ConfigureDbContext(); @@ -100,7 +95,10 @@ public void RawInsert() [Benchmark] public async Task Linq2Db() { - await DbContext.BulkCopyAsync(data); + await DbContext.BulkCopyAsync(new BulkCopyOptions + { + BulkCopyType = BulkCopyType.ProviderSpecific, + }, data); } [Benchmark] @@ -135,65 +133,10 @@ await DbContext.BulkInsertAsync(data, options => // }); // } - // [Benchmark] - // public async Task EFCore_SaveChanges() - // { - // DbContext.AddRange(data); - // await DbContext.SaveChangesAsync(); - // } - - private void RawInsertMySql() + [Benchmark] + public async Task EFCore_SaveChanges() { - var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - var bulkCopy = new MySqlBulkCopy(connection); - - bulkCopy.DestinationTableName = nameof(TestEntity); - bulkCopy.BulkCopyTimeout = 60; - - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(6, "NumericEnumValue")); - - var dataTable = new DataTable(); - dataTable.Columns.Add("Name", typeof(string)); - dataTable.Columns.Add("Price", typeof(decimal)); - dataTable.Columns.Add("Identifier", typeof(Guid)); - dataTable.Columns.Add("CreatedAt", typeof(DateTime)); - dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); - dataTable.Columns.Add("NumericEnumValue", typeof(int)); - - foreach (var entity in data) - { - var row = dataTable.NewRow(); - row["Name"] = entity.Name; - row["Price"] = entity.Price; - row["Identifier"] = entity.Identifier; - row["CreatedAt"] = entity.CreatedAt; - row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); - row["NumericEnumValue"] = (int)entity.NumericEnumValue; - dataTable.Rows.Add(row); - - if (dataTable.Rows.Count >= 50_000) - { - bulkCopy.WriteToServer(dataTable); - dataTable.Clear(); - } - } - - if (dataTable.Rows.Count > 0) - { - bulkCopy.WriteToServer(dataTable); - } + DbContext.AddRange(data); + await DbContext.SaveChangesAsync(); } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs index e39fa78..286e93a 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using Microsoft.EntityFrameworkCore; @@ -11,9 +8,6 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorMySql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs index a803e02..af79db2 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -13,8 +10,6 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorPostgreSql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs index f8a2b6a..b27b977 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -13,9 +10,6 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlServer : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs index cc12c13..e65937e 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -11,9 +8,6 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlite : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs index d9fc5ac..cf71531 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs @@ -18,14 +18,6 @@ public class TestEntity [Column(nameof(StringEnumValue), TypeName = "text")] public StringEnum StringEnumValue { get; set; } - - public NumericEnum NumericEnumValue { get; set; } -} - -public enum NumericEnum -{ - First = 1, - Second = 2, } public enum StringEnum From 4c90ebdb3f05f79089e6ade734f9717e57d21d2a Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Sat, 24 May 2025 08:56:33 +0200 Subject: [PATCH 3/6] Revert "Do not insert NumericEnumValue because of linq2db not handling it right with provider specific import and simplify benchmark" This reverts commit 0ba0264b24eaa8b68b15f084e3fc274b964abf6c. --- .../LibComparator.RawInsert.cs | 68 +++------------- .../LibComparator.cs | 81 ++++++++++++++++--- .../LibComparatorMySql.cs | 6 ++ .../LibComparatorPostgreSql.cs | 5 ++ .../LibComparatorSqlServer.cs | 6 ++ .../LibComparatorSqlite.cs | 6 ++ .../TestEntity.cs | 8 ++ 7 files changed, 111 insertions(+), 69 deletions(-) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs index 1d5b602..1b60468 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs @@ -4,8 +4,6 @@ using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; -using MySqlConnector; - using Npgsql; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; @@ -27,7 +25,8 @@ private void RawInsertPostgreSql() "Identifier", "CreatedAt", "UpdatedAt", - "StringEnumValue" + "StringEnumValue", + "NumericEnumValue" ) FROM STDIN (FORMAT BINARY) """; @@ -41,6 +40,7 @@ private void RawInsertPostgreSql() writer.Write(entity.CreatedAt); writer.Write(entity.UpdatedAt); writer.Write(entity.StringEnumValue.ToString()); + writer.Write((int)entity.NumericEnumValue); } writer.Complete(); @@ -63,8 +63,9 @@ private void RawInsertSqlite() "Identifier", "CreatedAt", "UpdatedAt", - "StringEnumValue" - ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue) + "StringEnumValue", + "NumericEnumValue" + ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue) """; command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); @@ -73,6 +74,7 @@ private void RawInsertSqlite() command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String)); + command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); foreach (var entity in data) { @@ -82,6 +84,7 @@ private void RawInsertSqlite() command.Parameters["@CreatedAt"].Value = entity.CreatedAt; command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString(); + command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; command.ExecuteNonQuery(); } @@ -109,6 +112,7 @@ private void RawInsertSqlServer() bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue"); + bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); var dataTable = new DataTable(); dataTable.Columns.Add("Name", typeof(string)); @@ -117,6 +121,7 @@ private void RawInsertSqlServer() dataTable.Columns.Add("CreatedAt", typeof(DateTime)); dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); dataTable.Columns.Add("StringEnumValue", typeof(string)); + dataTable.Columns.Add("NumericEnumValue", typeof(int)); foreach (var entity in data) { @@ -127,58 +132,7 @@ private void RawInsertSqlServer() row["CreatedAt"] = entity.CreatedAt; row["UpdatedAt"] = entity.UpdatedAt; row["StringEnumValue"] = entity.StringEnumValue.ToString(); - dataTable.Rows.Add(row); - - if (dataTable.Rows.Count >= 50_000) - { - bulkCopy.WriteToServer(dataTable); - dataTable.Clear(); - } - } - - if (dataTable.Rows.Count > 0) - { - bulkCopy.WriteToServer(dataTable); - } - } - - private void RawInsertMySql() - { - var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - var bulkCopy = new MySqlBulkCopy(connection); - - bulkCopy.DestinationTableName = nameof(TestEntity); - bulkCopy.BulkCopyTimeout = 60; - - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue")); - - var dataTable = new DataTable(); - dataTable.Columns.Add("Name", typeof(string)); - dataTable.Columns.Add("Price", typeof(decimal)); - dataTable.Columns.Add("Identifier", typeof(Guid)); - dataTable.Columns.Add("CreatedAt", typeof(DateTime)); - dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); - - foreach (var entity in data) - { - var row = dataTable.NewRow(); - row["Name"] = entity.Name; - row["Price"] = entity.Price; - row["Identifier"] = entity.Identifier; - row["CreatedAt"] = entity.CreatedAt; - row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); + row["NumericEnumValue"] = (int)entity.NumericEnumValue; dataTable.Rows.Add(row); if (dataTable.Rows.Count >= 50_000) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs index 48c1e61..4e930c4 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs @@ -1,19 +1,23 @@ using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; using DotNet.Testcontainers.Containers; using EFCore.BulkExtensions; -using LinqToDB.Data; using LinqToDB.EntityFrameworkCore; +using Microsoft.Data.SqlClient; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; + +using MySqlConnector; + +using Npgsql; + using PhenX.EntityFrameworkCore.BulkInsert.Extensions; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -[MemoryDiagnoser] -[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 5)] public abstract partial class LibComparator { [Params(500_000/*, 1_000_000/*, 10_000_000*/)] @@ -31,6 +35,7 @@ public void IterationSetup() Price = (decimal)(i * 0.1), Identifier = Guid.NewGuid(), StringEnumValue = (StringEnum)(i % 2), + NumericEnumValue = (NumericEnum)(i % 2), }).ToList(); ConfigureDbContext(); @@ -95,10 +100,7 @@ public void RawInsert() [Benchmark] public async Task Linq2Db() { - await DbContext.BulkCopyAsync(new BulkCopyOptions - { - BulkCopyType = BulkCopyType.ProviderSpecific, - }, data); + await DbContext.BulkCopyAsync(data); } [Benchmark] @@ -133,10 +135,65 @@ await DbContext.BulkInsertAsync(data, options => // }); // } - [Benchmark] - public async Task EFCore_SaveChanges() + // [Benchmark] + // public async Task EFCore_SaveChanges() + // { + // DbContext.AddRange(data); + // await DbContext.SaveChangesAsync(); + // } + + private void RawInsertMySql() { - DbContext.AddRange(data); - await DbContext.SaveChangesAsync(); + var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + var bulkCopy = new MySqlBulkCopy(connection); + + bulkCopy.DestinationTableName = nameof(TestEntity); + bulkCopy.BulkCopyTimeout = 60; + + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(6, "NumericEnumValue")); + + var dataTable = new DataTable(); + dataTable.Columns.Add("Name", typeof(string)); + dataTable.Columns.Add("Price", typeof(decimal)); + dataTable.Columns.Add("Identifier", typeof(Guid)); + dataTable.Columns.Add("CreatedAt", typeof(DateTime)); + dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); + dataTable.Columns.Add("StringEnumValue", typeof(string)); + dataTable.Columns.Add("NumericEnumValue", typeof(int)); + + foreach (var entity in data) + { + var row = dataTable.NewRow(); + row["Name"] = entity.Name; + row["Price"] = entity.Price; + row["Identifier"] = entity.Identifier; + row["CreatedAt"] = entity.CreatedAt; + row["UpdatedAt"] = entity.UpdatedAt; + row["StringEnumValue"] = entity.StringEnumValue.ToString(); + row["NumericEnumValue"] = (int)entity.NumericEnumValue; + dataTable.Rows.Add(row); + + if (dataTable.Rows.Count >= 50_000) + { + bulkCopy.WriteToServer(dataTable); + dataTable.Clear(); + } + } + + if (dataTable.Rows.Count > 0) + { + bulkCopy.WriteToServer(dataTable); + } } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs index 286e93a..e39fa78 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs @@ -1,3 +1,6 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; + using DotNet.Testcontainers.Containers; using Microsoft.EntityFrameworkCore; @@ -8,6 +11,9 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +[MinColumn, MaxColumn, BaselineColumn] +[MemoryDiagnoser] +[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorMySql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs index af79db2..a803e02 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs @@ -1,3 +1,6 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; + using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -10,6 +13,8 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +[MemoryDiagnoser] +[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorPostgreSql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs index b27b977..f8a2b6a 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs @@ -1,3 +1,6 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; + using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -10,6 +13,9 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +[MinColumn, MaxColumn, BaselineColumn] +[MemoryDiagnoser] +[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlServer : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs index e65937e..cc12c13 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs @@ -1,3 +1,6 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; + using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -8,6 +11,9 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +[MinColumn, MaxColumn, BaselineColumn] +[MemoryDiagnoser] +[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlite : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs index cf71531..d9fc5ac 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs @@ -18,6 +18,14 @@ public class TestEntity [Column(nameof(StringEnumValue), TypeName = "text")] public StringEnum StringEnumValue { get; set; } + + public NumericEnum NumericEnumValue { get; set; } +} + +public enum NumericEnum +{ + First = 1, + Second = 2, } public enum StringEnum From 23ee8c13fa0a8eef85b4e1fe7ab12358997eb5e8 Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Sat, 24 May 2025 10:00:36 +0200 Subject: [PATCH 4/6] Optimize benchmark run --- .../LibComparator.RawInsert.cs | 65 +++++++++++++--- .../LibComparator.cs | 75 ++----------------- .../Program.cs | 15 +++- .../{ => Providers}/LibComparatorMySql.cs | 8 +- .../LibComparatorPostgreSql.cs | 7 +- .../{ => Providers}/LibComparatorSqlServer.cs | 8 +- .../{ => Providers}/LibComparatorSqlite.cs | 8 +- .../TestEntity.cs | 9 --- 8 files changed, 78 insertions(+), 117 deletions(-) rename tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/{ => Providers}/LibComparatorMySql.cs (73%) rename tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/{ => Providers}/LibComparatorPostgreSql.cs (78%) rename tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/{ => Providers}/LibComparatorSqlServer.cs (70%) rename tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/{ => Providers}/LibComparatorSqlite.cs (71%) diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs index 1b60468..2916f6a 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs @@ -4,6 +4,8 @@ using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using MySqlConnector; + using Npgsql; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; @@ -25,7 +27,6 @@ private void RawInsertPostgreSql() "Identifier", "CreatedAt", "UpdatedAt", - "StringEnumValue", "NumericEnumValue" ) FROM STDIN (FORMAT BINARY) """; @@ -39,7 +40,6 @@ private void RawInsertPostgreSql() writer.Write(entity.Identifier); writer.Write(entity.CreatedAt); writer.Write(entity.UpdatedAt); - writer.Write(entity.StringEnumValue.ToString()); writer.Write((int)entity.NumericEnumValue); } @@ -63,9 +63,8 @@ private void RawInsertSqlite() "Identifier", "CreatedAt", "UpdatedAt", - "StringEnumValue", "NumericEnumValue" - ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue) + ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @NumericEnumValue) """; command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); @@ -73,7 +72,6 @@ private void RawInsertSqlite() command.Parameters.Add(new SqliteParameter("@Identifier", DbType.Guid)); command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); - command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String)); command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); foreach (var entity in data) @@ -83,7 +81,6 @@ private void RawInsertSqlite() command.Parameters["@Identifier"].Value = entity.Identifier; command.Parameters["@CreatedAt"].Value = entity.CreatedAt; command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; - command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString(); command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; command.ExecuteNonQuery(); @@ -111,7 +108,6 @@ private void RawInsertSqlServer() bulkCopy.ColumnMappings.Add("Identifier", "Identifier"); bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); - bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue"); bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); var dataTable = new DataTable(); @@ -120,7 +116,6 @@ private void RawInsertSqlServer() dataTable.Columns.Add("Identifier", typeof(Guid)); dataTable.Columns.Add("CreatedAt", typeof(DateTime)); dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); dataTable.Columns.Add("NumericEnumValue", typeof(int)); foreach (var entity in data) @@ -131,7 +126,59 @@ private void RawInsertSqlServer() row["Identifier"] = entity.Identifier; row["CreatedAt"] = entity.CreatedAt; row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); + row["NumericEnumValue"] = (int)entity.NumericEnumValue; + dataTable.Rows.Add(row); + + if (dataTable.Rows.Count >= 50_000) + { + bulkCopy.WriteToServer(dataTable); + dataTable.Clear(); + } + } + + if (dataTable.Rows.Count > 0) + { + bulkCopy.WriteToServer(dataTable); + } + } + + private void RawInsertMySql() + { + var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + var bulkCopy = new MySqlBulkCopy(connection); + + bulkCopy.DestinationTableName = nameof(TestEntity); + bulkCopy.BulkCopyTimeout = 60; + + var i = 0; + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "Name")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "Price")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "Identifier")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "CreatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "UpdatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "NumericEnumValue")); + + var dataTable = new DataTable(); + dataTable.Columns.Add("Name", typeof(string)); + dataTable.Columns.Add("Price", typeof(decimal)); + dataTable.Columns.Add("Identifier", typeof(Guid)); + dataTable.Columns.Add("CreatedAt", typeof(DateTime)); + dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); + dataTable.Columns.Add("NumericEnumValue", typeof(int)); + + foreach (var entity in data) + { + var row = dataTable.NewRow(); + row["Name"] = entity.Name; + row["Price"] = entity.Price; + row["Identifier"] = entity.Identifier; + row["CreatedAt"] = entity.CreatedAt; + row["UpdatedAt"] = entity.UpdatedAt; row["NumericEnumValue"] = (int)entity.NumericEnumValue; dataTable.Rows.Add(row); diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs index 4e930c4..3ac6947 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs @@ -1,4 +1,5 @@ using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; using DotNet.Testcontainers.Containers; @@ -6,18 +7,12 @@ using LinqToDB.EntityFrameworkCore; -using Microsoft.Data.SqlClient; -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; - -using MySqlConnector; - -using Npgsql; - using PhenX.EntityFrameworkCore.BulkInsert.Extensions; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +[MemoryDiagnoser] +[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 5)] public abstract partial class LibComparator { [Params(500_000/*, 1_000_000/*, 10_000_000*/)] @@ -34,7 +29,6 @@ public void IterationSetup() Name = $"Entity{i}", Price = (decimal)(i * 0.1), Identifier = Guid.NewGuid(), - StringEnumValue = (StringEnum)(i % 2), NumericEnumValue = (NumericEnum)(i % 2), }).ToList(); @@ -135,65 +129,10 @@ await DbContext.BulkInsertAsync(data, options => // }); // } - // [Benchmark] - // public async Task EFCore_SaveChanges() - // { - // DbContext.AddRange(data); - // await DbContext.SaveChangesAsync(); - // } - - private void RawInsertMySql() + [Benchmark] + public async Task EFCore_SaveChanges() { - var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - var bulkCopy = new MySqlBulkCopy(connection); - - bulkCopy.DestinationTableName = nameof(TestEntity); - bulkCopy.BulkCopyTimeout = 60; - - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(6, "NumericEnumValue")); - - var dataTable = new DataTable(); - dataTable.Columns.Add("Name", typeof(string)); - dataTable.Columns.Add("Price", typeof(decimal)); - dataTable.Columns.Add("Identifier", typeof(Guid)); - dataTable.Columns.Add("CreatedAt", typeof(DateTime)); - dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); - dataTable.Columns.Add("NumericEnumValue", typeof(int)); - - foreach (var entity in data) - { - var row = dataTable.NewRow(); - row["Name"] = entity.Name; - row["Price"] = entity.Price; - row["Identifier"] = entity.Identifier; - row["CreatedAt"] = entity.CreatedAt; - row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); - row["NumericEnumValue"] = (int)entity.NumericEnumValue; - dataTable.Rows.Add(row); - - if (dataTable.Rows.Count >= 50_000) - { - bulkCopy.WriteToServer(dataTable); - dataTable.Clear(); - } - } - - if (dataTable.Rows.Count > 0) - { - bulkCopy.WriteToServer(dataTable); - } + DbContext.AddRange(data); + await DbContext.SaveChangesAsync(); } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs index 00eeb73..60b844f 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs @@ -1,6 +1,8 @@ using BenchmarkDotNet.Configs; using BenchmarkDotNet.Running; +using PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; + namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; public class Program @@ -11,9 +13,14 @@ public static void Main(string[] args) .Create(DefaultConfig.Instance) .WithOptions(ConfigOptions.DisableOptimizationsValidator); - BenchmarkRunner.Run(config); - BenchmarkRunner.Run(config); - BenchmarkRunner.Run(config); - BenchmarkRunner.Run(config); + var comparators = new[] + { + typeof(LibComparatorMySql), + typeof(LibComparatorPostgreSql), + typeof(LibComparatorSqlite), + typeof(LibComparatorSqlServer), + }; + + BenchmarkRunner.Run(comparators, config); } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorMySql.cs similarity index 73% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorMySql.cs index e39fa78..9504eb5 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorMySql.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using Microsoft.EntityFrameworkCore; @@ -9,11 +6,8 @@ using Testcontainers.MySql; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorMySql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorPostgreSql.cs similarity index 78% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorPostgreSql.cs index a803e02..3bb3595 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorPostgreSql.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -11,10 +8,8 @@ using Testcontainers.PostgreSql; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorPostgreSql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlServer.cs similarity index 70% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlServer.cs index f8a2b6a..8db3e14 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlServer.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -11,11 +8,8 @@ using Testcontainers.MsSql; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlServer : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlite.cs similarity index 71% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlite.cs index cc12c13..055375b 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlite.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using LinqToDB.EntityFrameworkCore; @@ -9,11 +6,8 @@ using PhenX.EntityFrameworkCore.BulkInsert.Sqlite; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlite : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs index d9fc5ac..ef9ecd2 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs @@ -16,9 +16,6 @@ public class TestEntity public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; - [Column(nameof(StringEnumValue), TypeName = "text")] - public StringEnum StringEnumValue { get; set; } - public NumericEnum NumericEnumValue { get; set; } } @@ -27,9 +24,3 @@ public enum NumericEnum First = 1, Second = 2, } - -public enum StringEnum -{ - First, - Second, -} From 59d68fc65e6b6902c90e81e42b092aa40f87cea6 Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Sat, 24 May 2025 10:46:18 +0200 Subject: [PATCH 5/6] Update benchmark results --- images/bench-mysql.png | Bin 0 -> 27575 bytes images/bench-postgresql.png | Bin 25474 -> 29071 bytes images/bench-sqlite.png | Bin 24708 -> 29077 bytes images/bench-sqlserver.png | Bin 25294 -> 29085 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/bench-mysql.png diff --git a/images/bench-mysql.png b/images/bench-mysql.png new file mode 100644 index 0000000000000000000000000000000000000000..d6933b8d6f784d3e4c5ea782980b23a3fd21a6ef GIT binary patch literal 27575 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�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 TZb?_gycKzAWvP4#L!bWwaxvUh literal 0 HcmV?d00001 diff --git a/images/bench-postgresql.png b/images/bench-postgresql.png index c0bc7ff93d2be134e25787df9dfc38c601a125d6..36fb76d5110e030c38092f37f914dbba0a6ca91e 100644 GIT binary patch literal 29071 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
AjxO-sgXvasV7O~%g$J@S-#&z7t| z^E;sNA|;~nUp&OH{BGwI&f^YAjU;@-b8cQIl03KFHOR)fKryu*F%>4untFZTXxZ<7S}qRpoCe zzZ6?S0YZI!ivh^~H|~PcGe*=NiwT(c=lHh7ev@;!qG2y*{j$wi!2ywBai@&lEGx}4 ziRp<}YoDD54X^%<55mttY)4fjb7L~G%?6j%cZMmQeL%*rqZ!RGX)RslcW3# z2lw>KGsOFzz?-WX#q1Sruxm3$OnOK*kMFa1kD&);f;CewmdZ`?AiPgt-fmu3 zOeL6i&==_K=^=N%44s?vBFLociDFf?T|7XrGANyo*wzvXduvoI!f&lO7Hre; z2*_DROyz6+n4NTjN0UuB$EB5oB9&kJjg3s1xC{65?^Q^^ax!4gdyPtwCLvi?ce0cl z|Hw`0(a%@AG!g69KbP56+etCQTlk{=4}xla?~9Hr9OSpQVYaD8D?~H zEd?@VQ3r-^AVQPJMtvM9W1rk4nnxPU6nmp!v6V|)vLFX(k|G>i!gKo+Bf!Ao{XfUw z9}~Y8T}cHhq$WjI``;hD2=8X{ph3i-jHPLP;v;fk)^N7$|JsCKV#S#7bMkU>;CjfF zETYNM$>u!^&x#$rpl^xem~dkrNI43=Rs(x7cay~}uHUrpCFBlzZgZ*yW6D#BRg5-| zfe${u@a%tbfXtF9+P0J6rqEBW1`PHu3{*-aYM(0M#?Q=W_N=L%G(I(S8nB3Lg10Ty z+|k`sT$n}dN{PYst~{db>VbPFnsi929B(plGd$6|d9ydRgu*|zR@?BDV_XTKd_p21 zMwVAvU*~Y%h`gb2%O5hYg}+=0-!^N>+?}sTXWTD*|7FmEOai?`3aWnaY#{=RjTaw5 zBXNtlvQZpoGoIm=1#$Z`>7>})*_CfSI-S7yV$2cvOkS#Md!dT?PNsED6=jAL!_PS| zf?eKm-OGL^L)Y8u{qJN$#;TNwju0NiR{L(h8Qh8R_&ma}D5bV?0WOy)DFm<-C>RD7r=l5a0VPF4W8bkbVd#2e$8XKllrbTSZ5Ke6KaV`tFC+ z9~mzOFVpV0mi<)Kr3r{UxmGi+eVJ9s2R2X8D`mHZ#4{*oO&}%c1!QosY2cE(2MQi1y5y%N@K6t%HBTuE)o=^bBt| zA3C8vo#7&#pRQ5|)HWJzU1MzUGj@EaK{>%DaVeXdq($+nW<2)}+KxD1jZTg!E}4z< zm{rj*#jq+lGw@y&+OR-m>f~;``^KF$e7mA7?u!HJych(t7MT=odDausIeUqR%-95F z3^SY?C7dW-BFqlbYZ!?Vv+-GP?5!nv{@OS)D5f@vWw@h#( z71~dGKeTUY&thx=KgH2ajno@CYv7abd{naT9zS4yC4o)HtRhyb2Fw2m5>jJXQlIL0 zB$BW-p0h!6CZYd*BB4*X?JxtYEYZKiK|d<>P4qc*>QH*hw^g9p1JY*>Kq!f0Lhh#E zO=ZF@z9fL5mFRw|{Yq1lZ_^x2k#H=c4`za%m|)2v2}=YFf53gUk9PDH4Q_i)l_FAf z%a^q5wC0lUW)xW|!iqjuUkT~9)-<{8F1X3lCQOmjUhR4vfJ5YHe(LLis~xY^K^1#s zwG{_meb5PQnEs_SK2HvR1`h(Y?_y+Eq+%#<`3rju+)W&9Eq&-DXIU2HPKt)eSWfW!W^Yg#GC*#>G{ZlENyF+TTmWWrk? z_a!z0o1fx(bX~0Djk(b^PEZ{f2{cAjYmNg|FQvS5N_65&oylf6X(gX4DF`P^-|y~O zSRdX`aP07TvVUa3d$TtAOCj=8p|Curf^z#=z|69wOTWdab-wD`~7cj23B2*t6JXJ=M{-Uxv|7pQa94 z1v3KRxd>+Osd}mWyZ;FBq8I7(gi34bn?KKQIUEY04uKvx27N^3J=lVCBv3io6@WcC z*e#;`7UHkbEJAN}VIR*BuO~jwzqWQfk;1HE&yP`m#aY4S$=Fg`XT^zs9)OR9ovMOc z=ESR=q6k0YGksmPgAeP}!i%R7l12BFSK+Z_GWgFp zZfZE>&QJbeG(dc4WfSa|R0qq}nc{JO6l4Wj$lM@mb3=KS?0~M|_T0XP_DF#&g)SWT zhP?PXb+cyyS$PO6W)yI0JOBZNto>;KQ5RjO>3Abuswlto>Zapsz!=YeW`QHk~_li*+b@Wt#} zXbb6pi~i4i;jc?f|AY4VZ~y844HezgbEng8W}!9s@uW3Jm;W`{PFKDm#*)$6qBJI} zYmuQbg3d)7O|cVWtyS}UsE{k;?&It0wbea5_lI4MfG#ygu3WJyCrr=)JO*&y_xuH7 zuRvx2Du<>Ok5n0E=BlCPZE(rdA%WbSKo9@5AXN@}WsFim;nse9;TK)_ykBL_COFef zd7pAP9!yLwaoe)U@|ih^Ro;O`o;T^s=x}OM!Lbv;dx*Kn;}wRKYuRxR0d;e$n$Pb=(l_-i;zyt;=eN@Geobm5G#PZ<*+ul}ei@06 z-uZF>zZ4$`WngI|bm3p@rAhZX5h647b`7iQJ-yzLmZ#^!PB=ozD0hE)-0tCrCnbTz z63z2JuDvN=EMZj@f=42ipP?L7&R$EXJ9{nRFg!M8c1m+Wskzv4!F!nSZur4c{kXmQ zY=vTLCVL^>hG{cXV%+ZB3E=&}!H$*hQo>E=);o-tZbQMv>?9 zN4^`B`e3tJ)?QWnFx`P>ejIpSpz0}J90p1GO7L$VLNNBH4>7#oplrN#{ie=Yy`P`K zy;{mV;phIJf)s>1pgQR<-Z1P>Ed#U?3SLEJ6B&b$u?Y9Sw~IDn__2E_3gr zNYdA5Jxdt*w|p(}mcjb}=nnygkCRl%n$#z$^$fnSB4D>b3IB^DCW=>f&JOyh+^Zzn9pP&4mdyk1Ca z?d$>Zw@vC%(ASguJ0GF?l1jI=V~m{OxI~Z9LvY{@DG6#EcVHUg+u^P9YUJblKkRih zVKBJ#XN#Z;8hu05%=u_vfHx%NE(`sDmH+sGWQ0HS1n_Y!8qimqe6)7!zL7mor<-^c z?z>W;^2ecM{qi*hab2Mt#Bcru?-*XB-yIio+oiG;pYM7)Ig74?oAY)qR|cg?)c%MM zXjjLuR~(+<#hnWCg_r-87MQJ8{%8-_C=zY4IL171_Bb8Ke_r3|{T?cx7VpVSZ(^w? ze^rzM`hsrl@r>Vt0plY;!H6+xVfM#MX}V+WSBEvUyOi-}{L@W-cB+UT?l-5H*C@upvY_raPUl=<@YkKR z8G#c19A>dwKI4kcgBE(!L~nJnjv0QY{Rke&Uz>PmQpGRJyc=$6CFbploH8$yf)v*t z(l8go_8ro9<|82;pY0zU2RBpfYZ;n8A7)84F%c_8@#T-hyI)vR0S$2Psq-T_azr)E?X_`-_H?9qI!%}xUADb4}$EM!5fS_H5D|Syh@7}A89Af3;I5| z{q%AiU+>mFE$#`*p;VuGf^xJp5s|6^4``fpBFGZmJ$3D|_Dm+HnLSGxSR~VJ^3%&# zvw~w+=&&A2LyN3GW>`~*q$LMqv<_>k<6Hft4tu1eZbDpV#SuT<$0-L9BA5mKsV|e2mc$Et(Fj@wyl0o;xiX~k z@joyfd)$y(60+*xDmrhIj?6_D89lk&+AfDIZ@Aa`t_X6!*-wYIba4#4DqcW99kJ2s zY>Vp{2ri4qH{6jl+*Q!21Mi$>2z>yH(dtb-lrlR zG^qFtyZ2a2WCl$>v%HFyG3S|I zESjzj(Qu82ix^i&7n*sDivL=aN6XeGbG_T-$*n|0{B+#G!FLRJff%>Pi7PJv;wI|4 zjN>bP8t_7jU`k3CD=9jyHWsZcPv=`mhisc zi$ZoJ&)rSHl?YE$Y`iHi$n`loB5tuD)4gh8_we;|HB}uMH_4+BofIS}m+hKCG31hl zJW3ICQgLG=An6*Dafomu+p68@XHa<54<=No#7@Ys$y3~ z@~v8t@8P+^t}J3*_EvCf$QA<2cD_h13n0P4<>QZLSycJvMHk3TP+nm0Hs!&V191w9GZ8hDVDo1{Es3K#cEt z@9D6{L})77Tx&c-G86}=cq5OTI`{>7~;agmNf zl_8T!fadE-Ch_%EI*@BTI1xq$s3mgO;jxQUqNEXJPA*DXw7hIVQzi5Pe!4J0R*wU_ zjJP@zVi_-+inJBZr-T(RlUBaxJx}+RKUFtrwii?66ekO-Jt^c)ly?rgJdH(aRSJKn z0G*c(He@b!u%(wkSAaF?m?evS`?`p>ChTv02&Od99W3r|+~zORfVO|-C?oVTseXa( zIEuABlKobxFw}vA8scr;vnYrU`n099|2c-`F4MgU@h2sz-LvgTB4plbl(=h08#Gh? zd~#2^a^Ek{JghmkW)sP2pJE83k} z@jht-Pfz?f1|d=d?kF#=r!l;*fEOPZ-vOscuQZ+wUDKK;N;P8*rA7ivN?R2LExq(v zmWsm80l2|mP85<`QQ`L~Pv{1loSA`3EXQjQno+$Pa6h5{{2&$g1YyZ;C~wS2x&SlF+3N+o^OEv?h9L$?}$B;W=<~r zsu+`;6?~1GVuUQp2Al?qUuLaaGm_x`2%(%~_m(P9dsTfWE93Qm1xktim%6&J6g|5= z5$*p=*3gwFe+9R}&9YtBK6zDRs9JYZ=)1|Zyvp}lKG{(Tb z>16_a2Y$J>HDgAe!reP|7GnD#vLOlN4*`8q7^7K<{} zt(<+1Ct18N@R=~D)BuIW9XWBRZ+P0dp1Uk>u#n?dZBjN%U(E!9YUX?b2YL|9ba-f6 zTEk}xohC8EsPkPXZFeNJRg({amb!oxT^sfcB`H(a-M)=nVVg-hk_^n^ol7RPNr^j{ z-W1dB3bw9Wr8-kzrj{pZ4=3K$^^{#;?Yy!~WpywEL5cNp=C0r2Fpz~@3WzOf>V@=> zx3=i9Byb}Xhtj*gG68Q`Wz#E6nI$q~=0+mkX7j97um;%?LzWK0Xwo=$VI7FqyDxa`t^Wba=KU zFm}OOKW$22S|J4xiTX!OAnQknDlkv`cr71%Y>t$z{3C}fnp9o5?BsX z(=hx3{DlCCuA=3t`L~fO;^1d@KmW6;&Vz`1kmwR8nQiERj>i50$qY)m zZAeLe=S>&5r?o36_~ccJR~&qQ1*v{)g17;7bX7_~9o@kOGC_7(&l18vw!d*NZ#{{3 z#H-c1yq2uk{>6xbebM1Jx|!D`3{GREKjsKJd~f1c8bt5vMWoFt)6)B%2`^wkQU!#U zn@jZ+LgFNja&TPjARNYR{FBk3k*ko zfY!8Bb)eO{7M7Y>p`qM#+qJrakN@EmxgKB~Gt zLewdhGNl1QC7%^6Ts!}d9rIx2-2d1gJ`!HvJUUN#n6ZcOwjaR68!{4#;sv5l-~1ne C_xQsA literal 25474 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 M3hMHOvX5T>53C6ku>b%7 diff --git a/images/bench-sqlite.png b/images/bench-sqlite.png index d43a0471ba741c2ae5e0bd669628b7be335bce21..cfcb1f6fabdf2bb653cf8d19cc2612ad318eb59a 100644 GIT binary patch literal 29077 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 Mr3@;#Z}{r}0OC!kDF6Tf literal 24708 zcmbrmWmH_*qDH&1pg|HeI0Scx;O_43u0ey7;6Z~0cP-rA-Q6t&cXxZFPoF-WK6l*v z#(O`Ys4B*wsI_YEHRt!O9V{m!`Wo&X8~^~X#l?ga006S;J9+##_`t|*oq1MCjcM-#D(~kJ|!PCyYeZj-aS8Wye|Ulc!NH#g=`0gCd9Xte@|-AY*B%S*XHiS*R@3Ccpm`p0@fc0cT%}KOcgnn2eXV z54ye05Qz!I$bN)M#CGa=)95+Zc0Jkk8+I=*FTM;pa#T2fftQ<@r`L=%V1M5Eb;H1O zVJG&t=V=24y)Le>#%V>E{RPI~O-ATU)<(Wo^55lCjz`SR?U*{y7qqQP$hOTNLj*0) zsqCb-fI_mL$w~C5My~n^!$Wmq?jqXOFe5x%uQt8?MGUrV=7yO*_(gC&qjAclxjBwk zwpzr4H$veo|J?5bG5L4k9WXlF70dRB*wNQq^VSWIc5fJj8ha(MV+P7Lo$fxoZQM$p zW7+On?0j%9fJ5}wzZmjcK9{k^=j?^0e`R30KT+>6+YvsQr*nVZ^tN$3<;GIaubKhj z*d{(Ps6zMtUfi-d%o5xEPE2R6nfY>|bvtE_h3(_^#w@hM6sk}U=44>&g(*@3XTw0q zs+G)5?*`i=a$^$Qn^6~+VUBY5ah7RHz4)fKc*EM8VJtGT@ku8qly&@?nZU~W{=P%_j^S$3D$Ro;2ieu`6^?$|Q^ z@=mP!9$7GScTm@@B9OtwF%|=twUle-4U2aq-y(zaky!X0bE#VOGM}qH5360X`i$jb zl#aMkON~`JO=BSrS-ARg+|xi!w(8rB!noHTr%J=_1gH+@XdNF~1xTPv#V)K;yv9e4 zJNo&l5|2t(;;Lx<-!@C_$IsGf@tWrKItk!o-~ozW1%vFx^n14*krLABIwx~3!v6ln zoxSdc=F-8O_<&)!UO%>e>8Ep4MsWix4UclY$G9M<5_D(ukzfWmGxCLZ(drOBOM#Eq z$2MLn!?4h_-YJDZ>SM*_nq^b{7*R0qr*pLe@Szm8Ckl_xp6)s-Z@;`t>C2Q;BJa02 z!QKBt8EPGzglQabWT@>6VSw$=@GYfN9&h#}@ZBpDq` z>(>-gcB;x~g<7p|U+BgKj$lEai3kOQLkmMvC1zleIoc5o@Qh`;&oz4^S7L`H{#1A~ zVx(|d=}l78zVr^AU(~Vkp6vy}Omr9;xoNE$J^3R{#fUNkpm4RbR6He8%CBLo&3}9sB{rM4Pl1KJn@5gQjU0*>YIG>2qIMr1u@S3hF zpogFH@Q?&6iKj%gav1}A@d@MQfwPB$Yy2r@;{DL zMr93Ome^2zAVab`b+J1H4~HpMb)P9EMV1cf55++01*?;OUNHmH$M1WJF}U{#E*SflV~=x-f-S=}c8UE09`VU&LQ6fOyj<31V)7#@Do_BQx3$jOBa?-1 zjR&_rB|xYJhUrjw*O_RZB?>h;mw!j|ahmJ%|Jg{_dfuw-FV?q$1D8W)H#kt))YN1D zuNimqm<;ky_?H60Gge5^ueD+u@sXaFEw8 z&*0y|(PHS6;lK1YzLXJ_rgcLH6Vus4vg_HszaNhZ#b9newbqgX%z<6&6%u91N+~>y z9TUV4#A_H2t#6dGg^0010_6AYd$|3JlNycAjMX=Ua>MY9@B_5VJm&Z}D(Ux{@~pw9 z9Hb9wsOOK%5btHru#_ShdVbJtNimSP2QBR~E>1R$y&I+Y2Fnm4Q^Hpc8_U>*46D-a z#Ux=%vy_N>Y5ZBMO;oCp9IUWOj{%Vid3!fo&FxUf7nLERh>=qOM{a>y8^5JXykNsl z>LLqC+AIgRT1k8$>>0f$Bs1lT%sBRX|K(5@=%!($jE*(xb*To86l=@{8nAN4+wZ!2 zXRu0-&$j2XHD78g>vik%X>U*vx?U1dVWd?gex4x^P znwujLFoGa=J{2>|Ou6Dm01$lEkHlDC?)G93^ta9P-9tFb$x!Kaj0un}if?A0UA7$4 zXPeB|RzIz%JLhYNEQQ0WA82Gl3-21w4=xGHyWX4WulP0=yFE3S#ReI4P5lfMQuen% zCtwgWTpvVi!5xuqzRi1 zi(HkoL&cGJPGxo#ub+USD`T!u7xAH{rgF6MK_St~iy~G60Q!T8qh#JT)*|S;#(r*d zwiyvH*S2xfxgxH=hQ`avxRZ%^^#f3#L<3AfctT<-sTvISUrLdYESuck?B8N`BFn!g z#peZ4Vpg_k>6ud~l3UXZ^G_HsE2fFg#|{p9JKq~L3a%JJDMSx8ui`PfP{OA^u1_|7 zVu-xqcU`lnMLDTco;LB5n3(lcLg!NZfsI*bimOpki#oTQ6B+56vCK}XM*=`sM9~Rp zpFQqzTlRdz4W4IE0f#n3@L^A0J<4~(S};GxHY>y>W_w1`MN5AADPchz|Fc)8WrWyz zX~lK*HT4jbiHx1Lsi|umXVkzuw>=BDH_a5rU66a-@Isod(piC}h1`0Qt0)ZeB`LgS zw5sGZL#gL(3c}J^gM5VeKD<-yIW^_reDBSjoH5kE*k9Ki=jpzeWPtg4aK?qC%58)H z!GDNOlIi69xH<}M*WX_Z)Etq-P`bE+s7 ziiQr;IK$wE)-RIx7D%^0%Ul6*D_3}zG|C4ew1wtpr!KWn$dGl21(wva_V&bCDOW9@ zRTdbw+^tsG+3Ainv=U&SnAriJh*HVT1o*)fN%gDIp)*2SUrvqwhrJbnBW&er=@DN) zL?73cEbk?TrRe2wp^}UznYVX}Aavr{kklp>kicN^1;ppIat3}b_0DlY^@{Ll6B+r5 zjxt3Cu*2$G?+3rN{mn$%yxuT4-X=~M4QvCXm@1&Hc&O{-B<*QFHEmfbubBh&E2-Ud zPOsVL!17@|=mcH!Z6*xcszVFhpgQ$Ome}#i}b#!+U=f)}iP{FD+IZh|~{Uc0AtW#tnrJ zR^P$%8>a17sl*(}DX;TS79;@u27y4-Ps8qSX&yV%C1xMWx6h`5Vb^w#+DQkaR;~vV zsksdA@SlCzWIvCB#(-X$l+hP7&wF5KA*AC<$RB}=$F5i1%^2wLOQ-s8H<5b<{ zm-X%K*;BF?kb#+V@#1}Kkdrv>yvUlppfQ3_*8d=fmg`$kK+obnH->FZx{FO&5 zzHkqsje5$8@sq!|4HWzrF8u*Y7n)N0ge-sH)4#we6r3AJ;on5{@(>;(#lN2T<1wVb zzuf_IW6%BzzEI&DxpB_2YDa@|Tm4ces2Co1SUln9f05M-VCh*dLG?L;A+o=~u65NQrRBTWux5|@Y)UC; zkN|#sBDd8}7^`B#L>l*;YW20U_WMUs3RulU3#34qq*d4yi`T#*2GU~_Swzhk`df2- zi0YGWO=Jb7sKe1Jm+~%;+jDxWrD62i6iMOmkzdtY1(b4y_zOyL zy?=_@M)-JcU(a$qgTr-0{vYqged^U;q$%UQ_44o2`!LKpo$C^@yFPh|}8XL*SZ9nQyumqG0aN~muPd0oQ~z!@f;fxpZI2;~f< zKi_u>?cGtlgTlWiLb3B7qlZ8+rExd1D#3r=xSNac$Naf#`;&twVxJD$TR_dFdqlgu z65?}~&xfXepA8eXyDr-%f16B^W1auUIR1N3QPY2$g?zJ}guHI|p=KDwi2@mBVY{NG zyPAEkUf$>Qmtj*>)cuDs2pW=r-diHW1{FSOz+(h%hxYz}DJKTML&>WOyz1&dsx9cfRxOYF@WD!@edsp*J_fWcWe~D4_0Ru5Dxn`mT zB>(3j?Eoi$g5LRD=UBb<*jW|gVD^azSth3^jw?^LmcJ-ZiW|SX)TRRfhI5XO2kLBx z@(SiW3^rs_vChMT(%ywK%#C<^J|qba%W1Cn-|R!5mxp_?!PmH(yA6OBCYq2$v614| zUrDoaRBSgkg8N3+hcH|AL)Wv2h52`W2`@QC{h;}Dg0 z3KCZbeYN4Xhk_xVqeKJ$1?Hh?Ua#Ue+)E zczzw=o39MphQ?ll=X$KAk!>;9;`XSXZ-KOBkqmFRQMc!kQOM;w5O-GxVct9V;m(d| zW<*`p^>nzhSeA}Zlb)BJ$ScllQuG$hO-jL;GXCDN8q3fjZ#J_t&g~;d@y|Ki$?#YT zpWggsJ+sh!MCO7q!=Zg4s2;9BmeL5#4f9tOchTjw;q-2S9Ej55{uZHFE}PYZ@K8ee z2hFcF=B=7-7EuGU`qNMe{2-H_@rWLOb`X9;RKmgzSa_ezb-FkY4*XC*r#aS5dD4yz zr$k8#Vzdh*mhXo@v^vUJxJOua*60nUJk|0=E-Tzx?jbyK_F5@zfcVk3)6Llo$JTTW z(4^f9$KT+4i#M`KuWQ?sww+vNk_{^TVFUU@cq#1NT`v&M@wDckx{EiKX2d(m5jmo zoV3q!gtu#xOoiT4YyHT8nrq~1mf2F5Pq)L9uVFr~cQF($PUz0ZU08han64lUPp?GB z{d_3U`%I-|fAV$X_K`7aRHQi?=Tctgvr;mxf!TPHKSEi8Bs+(h@Z{t4V$@8IUFLTu zA>1B;=ht3ny4nwiIDKOsPV)~H)&tkK#&UA~7at0iom*T&$GIq|l`*Tw2#QXAO#L z@pl}9+~}eMENavn*B{c(+=Cq z7*cZ52y#^xZf$S_oy&;)mO6!kejx-MIW(FJ^Vz$!vlk2!&3gA6Cs<!oKkbHF8`{;ql^F0Jy(3UcYo&9L zxoFa7Z2jsfsyQDEcfhV~jMIKcg95Kbb3mQ^))4h&HN!%BJ|2{wWw~U1`_K!^Yu%77 z)W>sY9m_LcVmqRn?7oGhYOKe4qKl6pHlOMo7!UtnRs?+2da~!o{0NS)<$8aeWgy(p zj8y_-OTPzl=|cvh^`>Z>SugcQ@ah*S@QZUe zEqES|{5CF-Pfy&G99w+YAKfYM{8*R=-%5}t00&@A3zyEhgZqSQysKiCi@k~pmBydV znm-DezV7EtYiQI41Mt?N>mTk0aS^tJBz;Wa8MX>PiIyyLMD`x|CvbLa60u2$a+anDPq+X69y=Ol*|`Fx0NavKmQPjto5+<^_6{qPrHg z`o7MtgrrwGhmlJIGD*Dl8J^bnN^6G>F4;bx1(lGeDYKZochL+y=~-Q#&NZJ{MCtG- zREe^Us}0t1*Js$@Fw)&cT(y9!H!80u2(y@C1~x6~yVd!_!D|LaT=z^QzH#xIy~=Z` zZ+>Gq6@q7*62HBLVnN*h77SqjXz6mq)%-!e#wz?fhmZ2yj&W2Y)vC1m+gY6I2~imB z`zn_UFu5g(k@X>*p8A-}ki^~qfZ*?PC4_-Prt>Kx8ofuAN4&Ms&QfAZRDC{w{Z{$x zs%j?BFwzsXz&w_RQ0EHR%Hj^(jMcJKWorJrjsYTlG##EKre-#bMU%dd9LlwOI_~|9 zn4!IdF3p8$>aY?!jCy0mJvOl-6M)NIw<4gW05+qaH9LS`G9TAOic+e5VBF2DN_GYD z+%j-A^)!UTLD02phxVmr>B|;+mj#Z9ZsaGKV5uN=M|-HR()lr$*OsUUFL+!Sws?DJ#EPXIC=s2qHt??Ujfd~a7L?pM4D?!rznXP2c z4&ykJNh~KBo2_*@RlFcd`YnzHLg35o`X>zAAh2&VMbz(`vvS50w*_PeD350$fHS1a zsy+}kc&PTnOqg)^I%%&hton~vm`qhZh0k#xtJ6q=j8NW=worCSQ5o`~8R5T53IQ$n z_B1R&IK!MEm`80GDm3CLN0L?sk+V`Fypz``@Y!-lYORHlxpDm1LAf&CHG%$0JNFn~ z@QAf&jFJxXN{5C_bq1$i9|euY?c4JDaV0<)0GG+;z5BN3@}tug3tQUN-i@-(f-2RU zw}l@OUPZZ%+g4q_?n^-jlzt{ivzX46_q$`0B5zC&5JR&W^W4|xVbl$>poJ>Xxt(o{ zIY=0Fu!kB;7ksRx>*t3dpe)4D_vyG>5R-HVI5DtGPl5~$V}QPf@-}q7J5Bs@@`(vN zK1jfXiz&3|kQy-B+lpEe5Ba+9!C$`Kim-lxbDPyWI~y9We_lt}xAt9=Z4rzbSR#{^ zzzhN7`{ru9yCwnnEZm7QLS9Z&UFDkz_(hCLG2BLHec3y{%A$rBi=ccE+54n{Tzf^jh& zUPr$2i8tqe5%W4;3X}+N&-Sq{d!`ZUw1zJ53HSLog}MJUKJ5Z1lNLMRen&aOP0+xP z5Bd`>lFi;v4-5dnoVMhR-R6E~%k4C6AV%+u&zz##ba+}h>eh$;8odU2#T9I>=v56a ztMfMdc&p(aSbJZvZ&B&$C*l(HfWU+2<)ETg(|8mb+RBG)Q$+>MRJQzfWygI%P@hzj ztG(b&22u|>wKWNE-iD)FR+2M!;SPh9QYaX`mCz;TC{_kl>XObw9wjF3-KEC!J_E-U zr~z*iBEF6eXuEJuO5K90zmBWoIbPV7cchTL(2qRp?IHrYl-7lMu2p6AwebBUD%qab zzdhbih;F;%ENa354TVC@oaGl3Jow(^Q#ruWb{YjbR0^k=40#*uPfxvcfRc<()j$%{kj0_n+J? zC}P^4N%Ov=g$D1X^^8gJ95SKBQF3}{*-ZAC=UwHxUb@+VV+cnlfMn^v?rlb65aX)* zu*sMAb#H$*%ggFhE7nUX`cc!QijV+$M&emZ_~S{EiZyYxPv`cqjO8@=7=hbkjm zigE)4N=L}8Ms_5#g2C@U2SO7Euvj4g`hWW=M9r5;VFym!v|yt|cwbLl{h}=#P~kL;x?w zqzD%k;NT+4Jd<9*D7qqt$W+#$KWGj`GFSJJlN|1}pxAi2sxZ5TGcfWthpOjM<7!jC z$u3EU?eaG`HL`>*E=1!{rz`sSsNTp^uvmFNgvT8!sf4U0*;SdaWieu>8i@o*xo|G8 z+3}@%RU)(%yWdwfE=46Z#8?XKH0bO&?o*eVUz|8qLtE`~5|IwX_Fj}>E(Nw8>3ICG zXn$(FvK>Ni3o%O4%BZ5BJQ-#eN`qz_z%hlo+lpIJa=9QZV_qNFRD6v2u|Zf9~%3yc7r1->Z-2T1lvh9olI?(AU|PKvE>c7s>+|-s3o6fR>hn?M|C5z)#V1|s1Q&=ou%p%S6bW{U;0cHuE!ZsT$ z$H_2>*S2UB*^t(`w4FoSU3KjC>#>KmTUKf`;o;%2nzC@E917+_8CDJNd)i$;&i+jG z;x+QB=OSnuhchh9u=zX@z$I0aPE{Vvv?7yyKI^B>t5m3o0|C<85d^&i+bc1`UQL5o z7@G0b`?64+N>1f+`eQ*8GQ#q)R$XGElA*-`4PlWy6b56{@E-aH%OYrpXJ3}wouK6T z5f12<`AQ-r=jyIa=T7O_??223XFDyZ5?K=sTx69zn;nNmqWJ}x_E?PMzWL_Dd2oA3 zTU(lb>^8nmm+gv2Q#*kK8PMAUd1~}p6v>#OnaP5O&O-0@d1T7~;d!vci%xH4e!qVh z;SqAZ<81)%y)t@)1=jW;g@gvCGbL$yGwX9inh}+$h}XM*wslQ7REIYvRoNa6yNhpP zdFs1iGAg35i+!z+l_*lrv&xpmIn(Mtt%oW`FTmL+O*fAWq&F)JR5G|zTQGh7LpMOmG(@x;n=DY$P3gdTj~#bhBr3 zhZ=C_Hxj+{1pd_p_`8M!9umuKt!^^n0pn=1<0pG40!SF~uMudXUS}DqjhVY$se`;x z=x)4^%IMySOovY?v7%TlVkIqNp=`pW!wTRQt*%_vZvbXdcpwtbV+B-@bum$D${K)s zPX=8Z)XFV4fiUKA`1B1WBhawNeqj&MOIr;Z_+T+UzD+at@n<%K1C$n(C3Jiud%4YX zN!8>qzy*&1O;xr9IC=$w+1~u+{Haqq92`J-s1n3wZ*BSRFuE~ z3us8XG^cs7-QERXqOA7Xaa7!Ot}YFM0h#_`+yP4bR|SS;ScbD}*bh|KJx=IM0`5KB z9YWd#1bS%l9MnpfjG0v`AGtpKG(*5x=n8DDPlHE5F}`adm{qrJd`(p~1aELW9Xo6k z7X2%m_A8R+*gnd$PCl8m32!Ped0E)-6%l>rV0FWje^vDHy^+om`?PM=HA){GxDXdp zR{a}>rNc7*P1;%vw=wd6NW#{PR>DL!IyaGvAEw^LtIzxzjQcLq?ub2cJZY__`1d2F ztvj}F6ua8?t@J|CnhzNM7jgG@RrR#ER+i=i6`j}P#;t{_I*ZNAm;RTxLwy`OM*O=j zB+QT<{mcKnSfk%uV#aSi2>8uGLN(wa-i|Mt3N>PmqrwSWO7Xf$uL`jK;kWcZ#3#Zj zRtCOq9yf_<$q?YocQ(|_aKHPv?&OTv?4CQy*`gh~< za&r`q-uX4xgsr?!x!|MAlCIrG?>uXh9N9>7WWRj;L%vK)V**{ZHZ30|5KO`gX97#k ze)3CpUI*HE=@yO2!zVTA!JdWTJonp21Y}QIMrp(cbQ9~QwzA;}6-xjmZRMAJ?!3ns zV89l%NZ05a>pSvR@Nz6sRlT9HY{@F3-GOmh`}@@f65GJXdkl!OT%WXA~d(BTxF5Jb(r?#-&N zhON?^CSNF-d*j~_`ffr+`&%&zJEimoF>VZ0R;pJ=lrUm64kf#~sXV5wwm3-BKa6P( zw0cHrPGaow2wD@V94xiCr6>`-I>v15`G$NCVr9KnIP`oa)3v~{Pf6F}T7$+g1+VgC zpUnQdqCpEuffN;?TiI2vTWf|kyIrE|=z6}9Txd2=A;WlYEA_$tFv)6(le;f-?;DEE zEm3U4zg5hi#f-kS0};`AB$ea32SNXhK-tlvC;31!K>)D(RS=QMBUZShe(@us%?>90 z;Y_xvHheJuRmXr#sosIH!uar{n-S%!`hN8I`!^5Py_Ajo2z$8fpN=Si-q2tEgBwef ztW5oNUVnQb8q#cYQqvKtPNhN6TOT|7v9G!Jg|#Hbl50YA*zfiBI$eb)gF6&(XZCZY8#8HY8gmn1Jt6HWAcY7QBg>; z3~`sMz&spONm+L9=Pt(NQvI#M|Dm1xWncoc)Qt}SNPR2ndgy8 zSG;~~cof93*0x#dfTp*9I?Ma2)hJ6zV6gsX>e-~vhf3{CWR7Zu%U>!AGYMU{2w45G zk+Y>*J_%`R?5waCM`f~KD@1KqT~=u)6DrRqI6f0!bf9zV3Uu??u@97ZUplT~Y$%C= z5o9&&pt;KeWAc)|;RrT#{c{%|xf2gt)I8Ig&I=kB(SRQeUXg>PtxN4d5T`xA*h$u6 zX^cSc%#Z<2=q)7&`RtJcj=ggK^gnz681>n2+QCO66DeB35JaG=JR$&9pal9*Hlh?+ z7EDgS2*pQ|8JQNS-lO~xULaEUa;(Rc{0rAx#dgvj5JEi0duoGF{S--9?EpV%ok&l6 z7E@YHiHdg~y$$JK!&~)3555;8>8=m^ql-VZC-q9W?LtYOJ*w*=p8NKK@ws@iCMQKXVu zc}ZB#Or%r84XO`+xL%09mN##_~X%poArGgGlXy7I*)SKkQlXK>mk5=Nh z=`+0rB?yS1(t<3I-tAi;%@MXSWs66RGUt9&E>m;$-GYJ*!8BAe75L7tAH6JuuaYqM z#zx&W?)$8o%(iZEr$}imuT~|Et2B{LOc=LiY zIK9&0t8XgWUSsYN(uuj3TC+ z_=x^60Rn#jfBHX38HP*Cs;PrGJWL*(V7~`k6F>o`W_Y6r^Gjv=kq6wfzfG+2@8~QH zxxeV@x1^r6Q}^4W_z(c!dH-WASQFXvjG`({0HonH|DL{n$B!p*q z+*HODF&RnXgYt*ElE~Qn@bC0OJ0?`l93&8<*+O4}=~%MyO1ReyA|;jY{`^2O8_`O# z6Ew&j@DAtIuk$B0GPO3;slWlQPScWBOJJD1)(qBtp;YEjdKwJc%9$%_>vxsT+-p_0 zDPsjQz?j$R*r>bPnb7WSXfk`>-CY>lPYeA|eNU@leRuA!>LbFy^vXdnu_m@py~OvY zis2*I>@~IPcG<3Ezr*wkJa3Zabfllqsk-KQsSxePZVSdaYAUnFYH)KuCUk0JT^onF zMxep)j~y^{GL|+y$kA;R?Y{vj(63U|Zf1XaHdHS%cqBeSE)n0H-EL~h_GKoONRiF)Fd~%U7s+B_p9q7`qHs5PMStSz?$Ws zMVnM6*$ZPS;kBG4b8>f1Q?FPbio$K+!UAt2P+jr8cT(`n=0MwZM)V5O$2TkosnNIf z2Od1=^%3GswCZuF!0PWgKfFxif6!@s3ei7H8DImJ@3=j*55Y9=!h?eCHwy;E>IKa8 zO;!Y&+i1yh#x-cf-KSR{HpEL(#?f|UsFy&H6z&6K4V=@{0`wZZFY zzcGhrABDH!cF7_>ACH~u!m=eBxwY&l!UxSGNp7V((-#MThJ}?YP>6A97;4__u?pN} z!_fa#>{yz#og})8ln5*OlAPiX7r=9;*p8^IEtH!dLjG^gOh}W*R`*w-8l^9KQYs5C zx7iVkN;p~O{6NdD3LwSnX9_4v^%=s zPJFw0<^zaQ{i0MT3GA~EwG}q^nAqO+eqrw30k}xMm8H=sVj8pKqW39~Nl2)7%&gZF z+FxK<-RaCgFK>LWu2@#x$K0Lb=WX7rj^?WKgb=n7c9w!-g4+6ZsEHW~iqW2f^89|S zk?k4rO`o;-(u$kOWb^CeA}$TVa5dfcJxN5-CKO=Rt6ZrXu)yy`+dnlQr5IC1f1o7A z=WhLk&)ZLv8}XLHg1q@+KOs!N_o=^~=BF)E3^N4tKkF7?FG++WYQX<{j@u(uVUls_ z!b-0%bpew)UB+A=`|h^`n^u3>+tKv1~TtPR=euWAh(m$2d4+P-k} zgl`cDZxUotGPSpMb9?Lb5RBi<4StofI%?;UB`1aRzxUjmkIj$&Dq^(a{v+V`msR^) z|0C1#f9PiX#dN>dL4NN7r0=gq;x~JWRE3~OXUJ9c{O^Sowi>jCygzFPnAPWMI-$5^ zG7ru*0MIsM&o}K`kcL{5&*Rj^?qRnR{ailj@Vsp15@Yn4|}8tz?jzEQ%UH3j|be>VKR}YjRc0{AhpNiM2~Nm zBZrB17GirLGPiK*~)-h(zGFex(2zSclJodM+^Sbo5 z>MT5WDCzL3m_59AwywM3aI49kvQhslWbgZ?zWYYzXh~qsrb}?b$(eOO>~oH zifL!VO`}IEGMpKQof>MP0X`nYz1|f|S%kY6iP>@6O0T{2gdV8Jb0f~Ekg*T%e5G}O z3`td1!|w@9vZJ8q^F@~u*Z_Pt$=g~adrP-XciFDHokCUy<601OnCALial{``*o@Ml z3%Y!f{^Pw`>noC1`VM5i#90`}7nDmUD-cy4M;Q7)y&p&pSE~NRZ?Tnl$BhNH`JQHs zX+-Dhq`FF?qb#o#Is;yc#ZJOsQSrt*z^80TC<-R;GtD{;F@|-MAWdn`pWeprNC6~>7WF`LgXB!Q;caBD7|7Jhs1b->6 z3ahc(XH@a(abCV^;%f(O)>f;e zGiePhz@S)LwyY2SmG+0Kda&d?#6U~51sz+D_{Wm8g|0G76g+18FvCh7jrk?)>T40q z2jLkPsPW#2?v=r@!08mJf2Hj}eU&lqvf00~8VlT)D)&=5eg*vNdec2P)<*LBGrprJ2RlwX-ZJYTl^#JrR$#TGrj zM1N1z?Us3)96K*wpjjgJ`MAd1@WjeAJhS@LXsKEd%EYop3TxGfCrH(P#cGUtGpm-T z-+c&;+LibK%{EnlR6JBVgbwe2z}#*Zrhh;i+7HR0%PEAXzA=c9MCUG}P5t5h^{0ud zX0Q6vBO2xK6l7k(DvDfZ^m-l;I;9_zvWhZT4W9R-;fW-x1W8qLi0q?n0D_V#nqfBR zOELVOqQeXP)yo zEo-Fqx)Z-;2bqJ!^KL86P%t35uA0*&RVQVx6}d(tg=s zu~U5(Xjwy2D&A#@;jYdwJRSVl)>>M@UCqlRI{c=fNOnGFk?as+70%I{YJil1C(n?vte2L6|9h#=tE0B_!Ri*KzT^IqFGmFh{zDbPU_po$--{(=Gvn!zT>zE{j zdoZ5O{mDM4-FhS7GYLM9mHWuHgSIaF!A)s?k&Yi2TzBTL9Q{y-E{505!*e(Yi!}oK z3yxR4QzdR2c$?>0wqH3WfSPa}hgSj#iy8ot! zz|KWQnQ+_!M*s@QqGKMGDIqLS8shSn{XY@E0sKF_F4dw}0G}~&F#P<_h3NMMD5GA(&0p28Q>d z9n(Ljcw;*TCwH_Op&+wUpo4R{gvgq-YWrJ3rXre^)y!C+5?H{Me;j2hJ}+sy00hdv z5_e@@0lh43Z?oFj-5wLfAX?OW*>m%wPh%o8s1Rv!PM=#W-v$>iiv%UF z;%dt^Ew#h4_TZP~TNqvy>hmm3G>JG(x@dP2`YGUkzNH<3(AYc6sbkE_wGa5W8-O4{ z%riuDoX%wWd%Dd?ii@rNg4(}@%RV2bKUQ5gg7~Rbi1o^(dxk+DfKPIX<<4@zh7zcr zlD?zx@M`lR9F%Srw3_s0pZ%b1^LXdVjSVygT88aSxlhj4anw@W#)QdxP-@j8d(cVBg_mrbh< zP9EB@NH(deQdeEaRQ^xSJqYS4pLbWjFRPCR0}!D%cG(7jC8bxWyySFRhpgZdHhUuZ zpU0a*K$^F-PGzEHhvD_UqAe!6C)3v24`cqnB5kH){l5p=WhuQAp;X@uNeEoLMNL^e z{~-hP$&0>0zZNt$ex0)fmbI9M3ZXQ`+<<_326iKet7U>7B&;8M7K0t066yB?_eKzh zRv3`2Dw6nmS*a=p&$+a?!O}&Y=KaQXU(WZ21}x!dkLvEWe!^kAt?LDWGZ1muwcT6pfb&>faf4!SWVD!Iu-6JMDl%C2P{^X!JdaUkGBb zCs@+7=8=&Cr-#NXqV)NNy+6>awpCX+`xFGf-M>1P;9MR`{}Ssg*iJ+zrp<=8Gh?FV zw9BCJ1{AU+{^;;wQF8@o_^5vBOl3Re&Z3&MC;XNFbUf%PHNqQZX?{>G%O>CcE9~iFQUSd2-XG$V8@wjEy=I@wayu+S{9$R~EOXL)zKul01FI{D9A2F65?m)vX9b#2MHw5W3tn z>ppYbxO~xZwOIP-NsufNM&sK4k(>_vbFmh@cuT(xez(TC9B7ft5HsR;mFmMxo)g_Es?L>d;3 zMugGBT49C!3rjx8fZpFM#X5T*oBadXAosf{nNo3!@g&GNO2B74b-Pdwa|}bOK}{%T zT}T9;1I2Q?sIci~Ykns0dn65Mw!uF)LTo=0?Hu9Ct@Hb~+h5tBm@M+X`wVo8yYlmiY^+TbDZD8oMgZVcQ&HbK} zLU4SO;n2I@APF5aQwO@~6|(j@En{doK-L(^R2_@uD1n{P?Np|;{A8k*V=KwiD=EwYi+Z7v26gNx8)-8krVO;3vZ@(LG=IvJ-b zbN6Y_TG@o~Z3H#8;}fs2&`@+k4q)j=Z*itHq89TmMik z%09)ty3d#oQDF+OG}}KFpOXlEQTRn?>lV*$Bi?!~IEn`&cUqKTimq_-ZqswH;~3Aj zx;31@+f!x(k@DIXUz^E*oqS={Zo$;F$0y%J6UaI(qK{>7!0Bx)C>wy^O7hNl%}Sbl zmv35ZGQ+i$d!`Ajw*Knxr`%(3$ncBzcs>75Kz$o%I}a`gHl(HGM&4(;k5Z>)t@O8|MR zjAZQ*Ks0t|rxrE+gL4MT2@kQ~ZGkFnFS6W1rV4T=|IIFFZ}-?oXv^Q3^;+c66LmxM z0GLK_uiHuqTTTuBM}^-sP$#(N@=MdKfvha6;_r?j;gw+W$g`lP4Zj0C_UhUHCC3P*^rT_})deC8>h6gu@~yLT>mVRgvhe0eXto zXM?wt#@ryVzqRRozg9@r$}T{+pzS=V#7G->$iV&&1|y!v@#oCZlB=7O!F>gX&KB^` ziyHXI{n|JbRhw7M!{qmog*i-c9E!2tsjutBltfs=CLF)Qg!t|H2FN=_!lLQFU(uj^ z5(@aScVKD5b2xok*fdq^D5@&oYr&#q-ScCw)mZD$6qZQ6tE;jUE}_ZySE4T!hb<0e zj)aW{=&|cYvQ~a2SB7VBKGkGH=Lk>2X(ciGjBOZFP{8-QM+mwI=O_MJ71@1&fC81y z;dKF>bU=FdBNKF$US4wLgA2|jnE3vdPLHX!h-+}rk~;6abjSsx8G%uyA3a5x=x>#J zTl@H?lnx0g8A5?)XpkIALL_A9LAtw< zt`ShWB$P&wuAwERk z|8T&=!=hqf-rZGvN`S?pt_cC7Ra)!XID(h`YEXNrI9tNXwnkI8yO`8{Z*kBW#vID4 zqx}Z>TyJP8zrs!iTS{-#_|?D9>-oU-YDg?C9)`$?pfIBCnvx zz$Me|*HPMnTumi%1v+c9W7%~(c!k6Jp{jNF;OMBZz@@yCNq?%MISehdOXjXa26}>} zZ((6Fc`(JR{BYs?OF?xW>V1;ABeTk69j~Bl%C*>+bmj=!jV`WXdy6)eVy%A& z$7F8$5J!NL9#(kLVZ^y7D~(J-Nkx^^iW>h5!re9`H!zizQ)O)JZHXUv z2$O)R#4y>DGsjDR0+|1|9YRZtA?~&veWWk%a*vO+vSAwq%xX$&1VID9s~(6@n*-ge zug|1mTulOWjpspUB`e1dVH$Ka%gZbtrU!uaYGP9`E9t|?p2YG;z@WB%j;aTJru?I> z61#euq5thLub~U;jt5hle8MCk+#+~xNqZL|F7X`u9Z0c1Wa2dwoHp0Oq!nvP!(`V= zwjTcz&;5b!pO2`heS}#ZtjMK&?>tGQ0i+uLX;3#t4MYEKN^#ow;j*b0JeO-($2|55 zDZuz|Yq_jS_ZO@p)T-F`IT8B!!eve@7frskUvr;+ZbX6k)xY^ZTe3g-xh9aA()4bg zmCpGSIi~X01Q7Sh%71|}P0;(6mV)uF86*QDe?R;qJ8bFbkmR3|G7JcpAI5ZMyAQB| z*xtODKSxx(9JjJ`s&rF#+=HcZ(^(&-GL)DNd7O9QhaF`bU(c~@opy<22K>a&f1Bz< z!r2|Xl2e{HKepEE276OTkSQ=KlHUYbUSrZ=c8UOiP)G~_m2Tgo==>smqWSg^gH z=BtZ${{`Ous3V&|)I2gQl0lwwkbbQL8GD^xm`umOu#PnDXfi z!Ql;p?N1+(iGg?LZ|<)H!B5eq8%y!w*UbuyuQbiBu4#cU{~eA{t<%4hu<6`iB z^wY*N47@KEt@6Dq-@?Vo%H=!%eZmZ!37Rj@{+8v#7+@V=x?abZ#wC4E0pf_g`YBuK zDL)w@@gWG+qLtt&X1$2!JK`>2EiL)Rr%(Ifa0|Wt-d9A=!@{w>D3e6suJl1(k)TVp z2fKD==dx`4ps2cHHM#+plt}4wVJZ3rk=^!%2PKpKDFy{NV_AcX5LP$n4-3WgizBF0 z35N7%s;UipT~z2>BW~@|H7iVM`|}jxBOWp!HL9|Z?u#;@Vqo}|&COkCViJzy%Lrh?@(|7hO7?7rt^iR1!)5he}5u|k(X_~I?MdJ&E zmaQ+ze%szS`837jFROckPGSgjysJ;H-ALEBP-g_-DaD0YwK~;RcGI1)C1Xk!j-D3{ zy?ltBA6GCbs$Jq}pL-^5-b?aMRy%>i>t>#w)NlbC^H$R8nd<1rPoLJV86SoU=dMmh zKh_>iJ|>;3!E?py0{NFg=hG6G*4SdhWzD6=?eQ*8)o_bC1End^A+5y-;h<1n(f})0 zLdyC#^N*m-dD~{^2ke%sc0t}Ea-`VL{y73`3EQ1@$^O12t?KAv3TDLpYlO-EYXX}j z?C+>kewqla3`pB_e-;d%T*K2&T}zEJv+&pv&&;WL_dGN$;PK= zqSk1IL+1}5JF94k8hsasyB!zwW)JcL9)^(?y}kDYI(9 z_!low$EPXxh3FOa1LPEN^SkZWM_FL^`c;}Pl741{P?lMWq0iqg-MfE zBQkVrQYsU-hd57PKjkvd8_gE-uDF?-+6>N+HV(3xY4CHVd)8YgyS|p^HCpbszWAfW zNSmontWcbiRv??JI9{$Y^=tjb)L@^!pXesy$Vu=4y9fHlwzD?BLqoCDYQ|dhz6gtR zF?6{o$B2(Fdsq{I4;k*I`FWzHv{5Lv)K_vR&G_ylsb}Y6#j)z9ZE2kHTA*`I6T|O2 zbCwyy?#>~Obqii28MTckUvGB3HYrviL8iWrJ48rnuDQ5aSr!q2bF~bm?vb2Uq{!OY zx{6V`7qIIvUE-P~ic^sLsvOc;4Psl+tu(H}i(1BSYg~nX=s&~(sZL(43yXfpN)33O zkgjCU{BDEAZ*-TPbVqCA18$`bYOiy{P}9p-IPe4c?WMW$jf+G7GCn>YAdQ?G^5a@K zbjOQ7Fuyf-QSYStHF(<4EhVMVE&IjcM<}-2N&c{{l*BLe;QE`9`uSfHBxDeU@IARdQ;mpyQSf1 zM-H2&87nWkj^WzgXbnjc9n)jxfa0T9+Y()US}u>>CsSGD!6{|w=pSmS>dW5Vuo0&v z0YWw}HntG;`#Gcikza9rb5=HP2YSPOBp;aDAAL%4hbWtjypwl7nhbPb!d2~vSipp~ zWhI*O*ANlt&Pu%|j;$Vq}v`K9IYQCsi( zo#D81WXqM4dPpNa3nB5%qZo-y-z+))4I;Q6D>4ikO_ z$>;IK#(=-zA`)txF-o}|Sl;e$f%ly16ZYUZ8|m2MjSciZhYCNDCU@6Xf4))g$pT=j zf;KL@PM6hPtn|K94-zH~^h9Vc_hWv0ximmV4>f0o?SEiK?gqIfLfkW{vp` z_vAD?dhbCB%OaVgN9|(q3$3&0=8_Uzt6FEY5oA5}yzyhwg;zDSkC@a9+%3nxsbfbD zDP%1a?rQ;R+o+=*J~e{=7i#mL!36PMPG0T_wsanjLIWt{P%RFV&EWKyx68G30hF3~8V$p@ zZi81On?wak*3mEau0iuoNj4tX-wP$GdR;6}c7BzTObSMYEQ(zaje~-uBqR?C+ycMJ z0S&fLPWzTGKjIW%g*I!jXstu1^2?jv{=ULT-zlz*p+0_U zaXs&?%^940alKImCVsacG?efY(GQk|0V`bP0XyZj+F>Vy8}}ht_Koh@=vc`L&E5)| zLH)Y(S^b93l0duWDis+m>}D4#1d6yV>b|RUgjcV(ZxQWjnrSp}i6CqTWP)-ia1-FR zV-qLp$}KNhBSPUeTtd%Y3&tcHPE$1Mt7qzy0FOEOzpeXv{IL%XFxPxbg{#h)0fu-O zVTDe1>TWPai*-~bVFv} zgZEK$L_|Q+T}y3wtS&KPX6n^l_mWpXNm`48$<;BL-=s{}Leo&27*p;BV@WB!W&^R} z3xzz|007U1hSwYk@Vqpp83M_&=3c;X6dpF?&q`u4mq5u7+}=A${jEYQz6xKrJ~7O<%WZQ8U=0Hj+Gb`kJJyBs;->dZ|; zn8PP5`@$Y+e0!-of3{+s9WhUKyjY!yywKq{+e^F;d-1qie$K@USK81>zM~rcLSybG zw0i5XM+dGRZMo+@-4uBthVN3-CNz!2%89M|UL04zeRtX3qi=NQ?FHawF?O^7RDRLX z<2pD(f4WGi)b2JD8UB^J{+98l#z=-T00atH-MIf6tGqp>y7O|9JTU~Q#db`gReIgQ z#0(PW<;5PiiMr0Bf$T)oLi(PUC;B8=CkQT`u?U*dMYJe8_u<>-hg7%LMB-%U{b`7@ z?p(WG)#LAD1#1cd9svb1-!j~uXN@oATRIH!o|YZ$XxK6ND@}~{8QdP#{aDf-cdTF- zk*sC1+nkPgKGP9n4C2BLH+`P9+jTLU4#xe1$NPk5M!Z0(G01e~&29z}7PU~F=91B>yP)?N*jTF8(ckBK)0EiIl|@s$d&c~J(eU`dcJAJ+cyBKgT`Rz7^rZTh zwy%QV{+Lrr-M}N+5Al&!7)*1cR3uM!*ZoN98#Yr@xW3M4xNaOD%Dx;>R0oyQr=7=D z_hNjZe5g_WvGLm}CBnX1Wz>kHH8Gj;Hi(EMHY&;Uv7=IlF_rG8aq@p>61r`{^+sRY%#$aRL9YnMbp>jcmU(0g%gd~DW4)7__%W8$N!-Jdh?^z zDf4Ge=iO#XvMx%dwZ0%k3g?{BoDdK)!Ia}>oZWZV7=u+Wv$7{Rm&B$jF~MAdB;2ZTO~v~Q@I0;Z?_5Mn}>NiPK0H2$mv>_>=Mr`I>KeHQB$x-zg)o34P`$fg8hxhz+;(VeK3998P^im}f}5T~BHh z)lPGP!lD-8=>DYI0>4esL^|AlYt}2}-T+34)^J-K$2xGRp4C=2tld%y)*gPt6v!ZL zDBJtE_p;wxeMQ1&07B4e!2U&2sJpVUj<_AEXveEY9uMc`$@XhKUN)G1=>v9flU@I1 z)n+*@OO<8mt_3b1We*Bs4iGo^)dzb?Vmk{A7!=Vu-f9-$y7_d|xq z8b2$qj z^GB{{GL3XPGBr!@PGq8a>ISyd!Xtw*f396ir;YUH2|IRNGV#EGqxv^xEDMjIzuFJK zdF@RWg8d6$1_(HXM+Za0Pve_d1)(_P>YjzcU)`FENGa3v6%co|fgeNowfSKIJ;cNmQECE3;Ep!Z9q zRekdJG08JSg>4WxJq5~}Z*-TXvn)--ErPoF!mQ^AuSsB%QQ;RB_Ad_VQuGMG$N97u zN~nZJR>s}A`vRr%k`XM6IaleRSjP;{6-PXzt)w#dB&N;i`rae*MmE>#&o8gf*@Te* zqehgYv5rsAkcv@Gd{d)e=VX}ql%oEKacm}HY%t%>9b@K$1(f#1$HI^6N z_uD|?Xa^kk471BP5)-+aajo7_$7J%SixKk%jvr(kZDrox9=c@ z(^|Zen@B#chm$pJ2B20Rb@2Gi{#?RvfT-MK%8c-V$QAkEMsB6+PT^2(XQ)qi7tT(A zFSG~tpOk+GMa?B9ERmO3ZUOnhB+YKaTDalt&vs-uu`37!X1_1ge3-UxYm}$L!31nl z7kk>v5F4)Fo>%TB7ww=B0ybfSBMyeM8#S4>VKS`tqT$>}kqtA<}Kp)V`F2nLH*=Q;qRaV@3kbV+3rk8WF>dpjyMc{D&*@xE2JC_b9JH3bnw@)iz8-M{1H*>rrrBL!TnacinR zHB-8x#e-VN--wJ33zPk<|81i(N?!`|^SczR{?ukCqHyEfn7<+23{RY%`Cn*`b$p`# zFJ_n1`t1___qyQ!4ecFW*y-MPMP$H(KmQT%Z{o)UZb`T$Pp?cu*3|E20Y!OLxe6JR G;Qs+AJSKnu diff --git a/images/bench-sqlserver.png b/images/bench-sqlserver.png index 2f739bbf2a791eae0e7a5178e3e19284cc9eb7db..a0182877d2523eb34a22b388be13f1d1c6700e54 100644 GIT binary patch literal 29085 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 From e74fc5bdee0d5ad735bbdfaa480f74b2698766f8 Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Sat, 24 May 2025 10:49:45 +0200 Subject: [PATCH 6/6] Update readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index df55730..322e190 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ and https://entityframework-extensions.net/bulk-extensions), using optimized con Legend : * `PhenX_EntityFrameworkCore_BulkInsert`: this library - * `RawInsert`: no library, using the native provider API (SqlBulkCopy for SQL Server, BeginBinaryImport for PostgreSQL, raw inserts for SQLite) + * `RawInsert`: naive implementation without any library, using the native provider API (SqlBulkCopy for SQL Server, BeginBinaryImport for PostgreSQL, raw inserts for SQLite) * `Z_EntityFramework_Extensions_EFCore`: https://entityframework-extensions.net/bulk-extensions * `EFCore_BulkExtensions`: https://github.com/borisdj/EFCore.BulkExtensions * `Linq2Db`: https://github.com/linq2db/linq2db @@ -144,6 +144,10 @@ SQLite results with 500 000 rows : ![bench-sqlite.png](https://raw.githubusercontent.com/PhenX/PhenX.EntityFrameworkCore.BulkInsert/refs/heads/master/images/bench-sqlite.png) +MySQL results with 500 000 rows : + +![bench-mysql.png](https://raw.githubusercontent.com/PhenX/PhenX.EntityFrameworkCore.BulkInsert/refs/heads/master/images/bench-mysql.png) + ## Contributing Contributions are welcome! Please open issues or submit pull requests for bug fixes, features, or documentation improvements.