A very simple .net core library that can help to sync a large number of records in-memory into the database using the COPY FROM STDIN command. Â
This library provides extension methods so that you can use with your EntityFrameworkCore DbContext instance DbContextExtensions.cs or you can use ConnectionContextExtensions.cs to work directly with a NpgsqlConnection instance without using EntityFrameworkCore.
- Bulk Insert (requires PostgreSQL >= 17)
- Bulk Update
- Bulk Delete
- Bulk Merge (requires PostgreSQL >= 17)
- Bulk Match
- Temp Table
- Direct Insert
- Direct Update
- Direct Delete
- Upsert
- Update the connection string ConnectionStrings.PostgreSQLConnectionString.
- Build and run.
- Update the connection string ConnectionStrings.PostgreSQLConnectionString.
- Build and run.
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkDelete;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkInsert;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkMerge;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkUpdate;
// Insert all columns
await dbct.BulkInsertAsync(rows);
await dbct.BulkInsertAsync(compositeKeyRows);
// Insert selected columns only
await dbct.BulkInsertAsync(rows,
row => new { row.Column1, row.Column2, row.Column3 });
await dbct.BulkInsertAsync(compositeKeyRows,
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
await dbct.BulkUpdateAsync(rows,
row => new { row.Column3, row.Column2 });
await dbct.BulkUpdateAsync(compositeKeyRows,
row => new { row.Column3, row.Column2 });
await dbct.BulkMergeAsync(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 });
await dbct.BulkMergeAsync(compositeKeyRows,
row => new { row.Id1, row.Id2 },
row => new { row.Column1, row.Column2, row.Column3 },
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
await dbct.BulkDeleteAsync(rows);
await dbct.BulkDeleteAsync(compositeKeyRows);using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkDelete;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkInsert;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkMerge;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkUpdate;
await dbct.BulkUpdateAsync(rows,
[ "Column3", "Column2" ]);
await dbct.BulkUpdateAsync(compositeKeyRows,
[ "Column3", "Column2" ]);
await dbct.BulkMergeAsync(rows,
["Id"],
[ "Column1", "Column2" ],
[ "Column1", "Column2", "Column3" ]);
await dbct.BulkMergeAsync(compositeKeyRows,
[ "Id1", "Id2" ],
[ "Column1", "Column2", "Column3" ],
[ "Id1", "Id2", "Column1", "Column2", "Column3" ]);await dbct.CreateBulkInsertBuilder<Row>()
.WithColumns(row => new { row.Column1, row.Column2, row.Column3 })
// or .WithColumns([ "Column1", "Column2", "Column3" ])
.ToTable(dbContext.GetTableInfor<Row>())
.ExecuteAsync(rows);using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkDelete;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkInsert;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkMerge;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkUpdate;
// Configure Mapping globaly
TableMapper.Configure<Row>(config =>
{
config
.TableName("Rows")
.PrimaryKeys(x => x.Id)
.OutputId(x => x.Id, OutputIdMode.ServerGenerated);
});
TableMapper.Configure<CompositeKeyRow>(config =>
{
config
.TableName("CompositeKeyRows")
.PrimaryKeys(x => new { x.Id1, x.Id2 });
});
var connection = new ConnectionContext(new NpgsqlConnection(connectionString), null);
// Insert all columns
await connection.BulkInsertAsync(rows);
await connection.BulkInsertAsync(compositeKeyRows);
// Insert selected columns only
await connection.BulkInsertAsync(rows,
row => new { row.Column1, row.Column2, row.Column3 });
await connection.BulkInsertAsync(compositeKeyRows,
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
await connection.BulkUpdateAsync(rows,
row => new { row.Column3, row.Column2 });
await connection.BulkUpdateAsync(compositeKeyRows,
row => new { row.Column3, row.Column2 });
await connection.BulkMergeAsync(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 });
await connection.BulkMergeAsync(compositeKeyRows,
row => new { row.Id1, row.Id2 },
row => new { row.Column1, row.Column2, row.Column3 },
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
await connection.BulkDeleteAsync(rows);
await connection.BulkDeleteAsync(compositeKeyRows);using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkDelete;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkInsert;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkMerge;
using EntityFrameworkCore.PostgreSQL.SimpleBulks.BulkUpdate;
var connection = new ConnectionContext(new NpgsqlConnection(connectionString), null);
await connection.BulkInsertAsync(rows,
[ "Column1", "Column2", "Column3" ]);
await connection.BulkInsertAsync(compositeKeyRows,
[ "Id1", "Id2", "Column1", "Column2", "Column3" ]);
await connection.BulkUpdateAsync(rows,
[ "Column3", "Column2" ]);
await connection.BulkUpdateAsync(compositeKeyRows,
[ "Column3", "Column2" ]);
await connection.BulkMergeAsync(rows,
["Id"],
[ "Column1", "Column2" ],
[ "Column1", "Column2", "Column3" ]);
await connection.BulkMergeAsync(compositeKeyRows,
[ "Id1", "Id2" ],
[ "Column1", "Column2", "Column3" ],
[ "Id1", "Id2", "Column1", "Column2", "Column3" ]);await connection.CreateBulkInsertBuilder<Row>()
.WithColumns(row => new { row.Column1, row.Column2, row.Column3 })
// or .WithColumns([ "Column1", "Column2", "Column3" ])
.ToTable(new NpgsqlTableInfor<Row>("Rows"))
.ExecuteAsync(rows);await _context.BulkInsertAsync(rows,
row => new { row.Column1, row.Column2, row.Column3 },
new BulkInsertOptions
{
KeepIdentity = false,
BatchSize = 0,
Timeout = 30,
LogTo = Console.WriteLine
});await _context.BulkUpdateAsync(rows,
row => new { row.Column3, row.Column2 },
new BulkUpdateOptions
{
BatchSize = 0,
Timeout = 30,
LogTo = Console.WriteLine
});await _context.BulkDeleteAsync(rows,
new BulkDeleteOptions
{
BatchSize = 0,
Timeout = 30,
LogTo = Console.WriteLine
});await _context.BulkMergeAsync(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 },
new BulkMergeOptions
{
BatchSize = 0,
Timeout = 30,
ReturnDbGeneratedId = true,
LogTo = Console.WriteLine
});var contactsFromDb = await _context.BulkMatchAsync(matchedContacts,
x => new { x.CustomerId, x.CountryIsoCode },
new BulkMatchOptions
{
BatchSize = 0,
Timeout = 30,
LogTo = Console.WriteLine
});var customerTableName = await _context.CreateTempTableAsync(customers,
x => new
{
x.IdNumber,
x.FirstName,
x.LastName,
x.CurrentCountryIsoCode
},
new TempTableOptions
{
BatchSize = 0,
Timeout = 30,
LogTo = Console.WriteLine
});await _context.DirectInsertAsync(row,
row => new { row.Column1, row.Column2, row.Column3 },
new BulkInsertOptions
{
Timeout = 30,
LogTo = Console.WriteLine
});await _context.DirectUpdateAsync(row,
row => new { row.Column3, row.Column2 },
new BulkUpdateOptions
{
Timeout = 30,
LogTo = Console.WriteLine
});await _context.DirectDeleteAsync(row,
new BulkDeleteOptions
{
Timeout = 30,
LogTo = Console.WriteLine
});await _context.UpsertAsync(row,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 },
new BulkMergeOptions
{
Timeout = 30,
ReturnDbGeneratedId = true,
LogTo = Console.WriteLine
});var updateResult = await dbct.BulkUpdateAsync(rows, row => new { row.Column3, row.Column2 });
Console.WriteLine($"Updated: {updateResult.AffectedRows} row(s)");var deleteResult = await dbct.BulkDeleteAsync(rows);
Console.WriteLine($"Deleted: {deleteResult.AffectedRows} row(s)");var mergeResult = await dbct.BulkMergeAsync(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 });
Console.WriteLine($"Updated: {mergeResult.UpdatedRows} row(s)");
Console.WriteLine($"Inserted: {mergeResult.InsertedRows} row(s)");
Console.WriteLine($"Affected: {mergeResult.AffectedRows} row(s)");Single Table /src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkInsertSingleTableBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-VUKETC : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| EFCoreInsert | 100 | 24.87 ms | NA | - | - | - | 1117.16 KB |
| BulkInsert | 100 | 16.19 ms | NA | - | - | - | 144.4 KB |
| EFCoreInsert | 1000 | 116.08 ms | NA | 1000.0000 | 1000.0000 | - | 10733.77 KB |
| BulkInsert | 1000 | 26.10 ms | NA | - | - | - | 909.45 KB |
| EFCoreInsert | 10000 | 1,032.25 ms | NA | 14000.0000 | 6000.0000 | - | 101319.22 KB |
| BulkInsert | 10000 | 158.03 ms | NA | 1000.0000 | 1000.0000 | - | 8484.25 KB |
| EFCoreInsert | 100000 | 6,424.85 ms | NA | 138000.0000 | 50000.0000 | - | 997459.33 KB |
| BulkInsert | 100000 | 851.58 ms | NA | 12000.0000 | 2000.0000 | 1000.0000 | 78651.35 KB |
| EFCoreInsert | 250000 | 15,169.42 ms | NA | 346000.0000 | 121000.0000 | - | 2469857.71 KB |
| BulkInsert | 250000 | 2,049.98 ms | NA | 28000.0000 | 1000.0000 | - | 193035.99 KB |
| EFCoreInsert | 500000 | 34,492.82 ms | NA | 693000.0000 | 240000.0000 | - | 4946532.22 KB |
| BulkInsert | 500000 | 3,977.10 ms | NA | 57000.0000 | 2000.0000 | - | 387290.34 KB |
Multiple Tables (1x parent rows + 5x child rows) /src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkInsertMultipleTablesBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LTFAOU : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| EFCoreInsert | 100 | 145.08 ms | NA | 1000.0000 | 1000.0000 | - | 8343.67 KB |
| BulkInsert | 100 | 49.57 ms | NA | - | - | - | 665.8 KB |
| EFCoreInsert | 1000 | 795.13 ms | NA | 11000.0000 | 5000.0000 | - | 78542.85 KB |
| BulkInsert | 1000 | 188.83 ms | NA | - | - | - | 5941.84 KB |
| EFCoreInsert | 10000 | 6,722.98 ms | NA | 109000.0000 | 41000.0000 | - | 772122.11 KB |
| BulkInsert | 10000 | 1,302.40 ms | NA | 9000.0000 | 2000.0000 | 1000.0000 | 55370.05 KB |
| EFCoreInsert | 100000 | 61,476.01 ms | NA | 1087000.0000 | 373000.0000 | - | 7687142.55 KB |
| BulkInsert | 100000 | 12,805.28 ms | NA | 82000.0000 | 4000.0000 | - | 548065.25 KB |
/src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkUpdateBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| EFCoreUpdate | 100 | 26.56 ms | NA | - | - | 1056.89 KB |
| BulkUpdate | 100 | 20.16 ms | NA | - | - | 53.34 KB |
| EFCoreUpdate | 1000 | 118.31 ms | NA | 1000.0000 | 1000.0000 | 8172.52 KB |
| BulkUpdate | 1000 | 29.87 ms | NA | - | - | 415.93 KB |
| EFCoreUpdate | 10000 | 1,000.87 ms | NA | 10000.0000 | 3000.0000 | 75273.42 KB |
| BulkUpdate | 10000 | 175.40 ms | NA | - | - | 4012.16 KB |
| EFCoreUpdate | 100000 | 7,526.76 ms | NA | 104000.0000 | 28000.0000 | 735520.32 KB |
| BulkUpdate | 100000 | 1,395.47 ms | NA | 6000.0000 | 1000.0000 | 38947.02 KB |
| EFCoreUpdate | 250000 | 18,029.63 ms | NA | 260000.0000 | 70000.0000 | 1818097.27 KB |
| BulkUpdate | 250000 | 4,606.96 ms | NA | 15000.0000 | 3000.0000 | 97174.13 KB |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-FVGKFX : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| BulkUpdate | 500000 | 14.99 s | NA | 31000.0000 | 6000.0000 | 189.67 MB |
| BulkUpdate | 1000000 | 52.35 s | NA | 63000.0000 | 13000.0000 | 379.21 MB |
/src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkDeleteBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| EFCoreDelete | 100 | 18.97 ms | NA | - | - | 675.7 KB |
| BulkDelete | 100 | 16.18 ms | NA | - | - | 25.73 KB |
| EFCoreDelete | 1000 | 127.17 ms | NA | 1000.0000 | 1000.0000 | 6448.29 KB |
| BulkDelete | 1000 | 41.02 ms | NA | - | - | 166.36 KB |
| EFCoreDelete | 10000 | 941.10 ms | NA | 9000.0000 | 2000.0000 | 61677.63 KB |
| BulkDelete | 10000 | 209.25 ms | NA | - | - | 1572.33 KB |
| EFCoreDelete | 20000 | 2,188.30 ms | NA | 17000.0000 | 6000.0000 | 122600.81 KB |
| BulkDelete | 20000 | 324.00 ms | NA | - | - | 3135.3 KB |
| EFCoreDelete | 50000 | 3,430.29 ms | NA | 43000.0000 | 11000.0000 | 301041.3 KB |
| BulkDelete | 50000 | 756.71 ms | NA | 1000.0000 | - | 7822.52 KB |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-RRDFUF : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| BulkDelete | 100000 | 2.108 s | NA | 2000.0000 | 1000.0000 | 15.27 MB |
| BulkDelete | 250000 | 3.905 s | NA | 6000.0000 | 1000.0000 | 38.16 MB |
| BulkDelete | 500000 | 7.768 s | NA | 12000.0000 | 1000.0000 | 76.3 MB |
| BulkDelete | 1000000 | 15.895 s | NA | 25000.0000 | 1000.0000 | 152.6 MB |
/src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkMergeBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| EFCoreUpsert | 100 | 39.72 ms | NA | - | - | 2138.82 KB |
| BulkMerge | 100 | 31.75 ms | NA | - | - | 201.27 KB |
| EFCoreUpsert | 1000 | 446.34 ms | NA | 2000.0000 | 1000.0000 | 18676.95 KB |
| BulkMerge | 1000 | 60.98 ms | NA | - | - | 1821.43 KB |
| EFCoreUpsert | 10000 | 2,293.35 ms | NA | 24000.0000 | 10000.0000 | 175741.33 KB |
| BulkMerge | 10000 | 315.95 ms | NA | 2000.0000 | 1000.0000 | 17002.34 KB |
| EFCoreUpsert | 100000 | 14,094.90 ms | NA | 243000.0000 | 75000.0000 | 1735002.65 KB |
| BulkMerge | 100000 | 1,933.37 ms | NA | 26000.0000 | 1000.0000 | 168875.89 KB |
| EFCoreUpsert | 250000 | 34,470.08 ms | NA | 607000.0000 | 190000.0000 | 4292407.68 KB |
| BulkMerge | 250000 | 5,091.40 ms | NA | 64000.0000 | 3000.0000 | 418668.28 KB |
/src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkMergeReturnDbGeneratedIdBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| ReturnDbGeneratedId | 100 | 15.65 ms | NA | - | - | 189.59 KB |
| NotReturnDbGeneratedId | 100 | 20.96 ms | NA | - | - | 148.23 KB |
| ReturnDbGeneratedId | 1000 | 47.67 ms | NA | - | - | 1707.91 KB |
| NotReturnDbGeneratedId | 1000 | 49.77 ms | NA | - | - | 1301.91 KB |
| ReturnDbGeneratedId | 10000 | 234.40 ms | NA | 2000.0000 | 1000.0000 | 15867.1 KB |
| NotReturnDbGeneratedId | 10000 | 441.70 ms | NA | 1000.0000 | - | 11897.58 KB |
| ReturnDbGeneratedId | 100000 | 2,330.98 ms | NA | 24000.0000 | 1000.0000 | 157522.2 KB |
| NotReturnDbGeneratedId | 100000 | 1,674.64 ms | NA | 19000.0000 | 1000.0000 | 118806.84 KB |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-FVGKFX : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| ReturnDbGeneratedId | 250000 | 5.101 s | NA | 60000.0000 | 1000.0000 | 381.14 MB |
| NotReturnDbGeneratedId | 250000 | 4.681 s | NA | 48000.0000 | 1000.0000 | 290.02 MB |
| ReturnDbGeneratedId | 500000 | 10.377 s | NA | 121000.0000 | 3000.0000 | 763.73 MB |
| NotReturnDbGeneratedId | 500000 | 9.393 s | NA | 96000.0000 | 1000.0000 | 580.01 MB |
| ReturnDbGeneratedId | 1000000 | 21.818 s | NA | 243000.0000 | 6000.0000 | 1529.56 MB |
| NotReturnDbGeneratedId | 1000000 | 22.181 s | NA | 193000.0000 | 2000.0000 | 1160.27 MB |
Single Column /src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkMatchSingleColumnBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| EFCoreSelect | 100 | 107.695 ms | NA | - | - | - | 765.44 KB |
| EFCoreBatchSelect | 100 | 3.477 ms | NA | - | - | - | 60.54 KB |
| BulkMatch | 100 | 8.764 ms | NA | - | - | - | 85.45 KB |
| EFCoreSelect | 1000 | 862.412 ms | NA | 1000.0000 | - | - | 7361.88 KB |
| EFCoreBatchSelect | 1000 | 6.029 ms | NA | - | - | - | 511.2 KB |
| BulkMatch | 1000 | 12.584 ms | NA | - | - | - | 740.02 KB |
| EFCoreSelect | 10000 | 8,139.137 ms | NA | 11000.0000 | 1000.0000 | - | 70483.66 KB |
| EFCoreBatchSelect | 10000 | 34.499 ms | NA | - | - | - | 5127.73 KB |
| BulkMatch | 10000 | 59.851 ms | NA | 1000.0000 | - | - | 7522.84 KB |
| EFCoreSelect | 100000 | 74,961.618 ms | NA | 115000.0000 | 24000.0000 | 1000.0000 | 705096.2 KB |
| EFCoreBatchSelect | 100000 | 526.386 ms | NA | 7000.0000 | 2000.0000 | - | 51371.59 KB |
| BulkMatch | 100000 | 376.410 ms | NA | 11000.0000 | 4000.0000 | - | 71420.53 KB |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-FVGKFX : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| EFCoreBatchSelect | 250000 | 912.3 ms | NA | 16000.0000 | 8000.0000 | - | 112.49 MB |
| BulkMatch | 250000 | 1,010.1 ms | NA | 29000.0000 | 9000.0000 | 1000.0000 | 173.6 MB |
| EFCoreBatchSelect | 500000 | 1,516.4 ms | NA | 34000.0000 | 17000.0000 | 1000.0000 | 224.89 MB |
| BulkMatch | 500000 | 2,572.8 ms | NA | 57000.0000 | 17000.0000 | 1000.0000 | 347.35 MB |
| EFCoreBatchSelect | 1000000 | 3,360.8 ms | NA | 68000.0000 | 34000.0000 | 1000.0000 | 449.7 MB |
| BulkMatch | 1000000 | 3,810.3 ms | NA | 113000.0000 | 32000.0000 | 1000.0000 | 694.86 MB |
Multiple Columns /src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/BulkMatchMultipleColumnsBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| EFCoreSelect | 100 | 104.54 ms | NA | - | - | 987.75 KB |
| BulkMatch | 100 | 11.92 ms | NA | - | - | 154.95 KB |
| EFCoreSelect | 1000 | 1,129.42 ms | NA | 1000.0000 | - | 9372.7 KB |
| BulkMatch | 1000 | 26.21 ms | NA | - | - | 1342.45 KB |
| EFCoreSelect | 10000 | 8,849.80 ms | NA | 14000.0000 | 3000.0000 | 91054.35 KB |
| BulkMatch | 10000 | 133.98 ms | NA | 2000.0000 | 1000.0000 | 13648.6 KB |
| EFCoreSelect | 100000 | 79,089.28 ms | NA | 148000.0000 | 38000.0000 | 910681.02 KB |
| BulkMatch | 100000 | 770.69 ms | NA | 20000.0000 | 5000.0000 | 129760.33 KB |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-FVGKFX : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---|---|---|---|---|---|---|
| BulkMatch | 250000 | 3.090 s | NA | 51000.0000 | 13000.0000 | 318.85 MB |
| BulkMatch | 500000 | 4.753 s | NA | 104000.0000 | 27000.0000 | 640.03 MB |
| BulkMatch | 1000000 | 9.823 s | NA | 209000.0000 | 54000.0000 | 1282.65 MB |
/src/EntityFrameworkCore.PostgreSQL.SimpleBulks.Benchmarks/TempTableBenchmarks.cs
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-SKLMHH : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|---|---|---|---|---|---|---|---|
| CreateTempTable | 100 | 11.01 ms | NA | - | - | - | 120.83 KB |
| CreateTempTable | 1000 | 22.78 ms | NA | - | - | - | 732.55 KB |
| CreateTempTable | 10000 | 106.20 ms | NA | 1000.0000 | 1000.0000 | - | 6851.52 KB |
| CreateTempTable | 100000 | 335.78 ms | NA | 12000.0000 | 2000.0000 | 1000.0000 | 68058.16 KB |
| CreateTempTable | 250000 | 823.61 ms | NA | 27000.0000 | 1000.0000 | - | 170011.08 KB |
| CreateTempTable | 500000 | 1,586.69 ms | NA | 55000.0000 | 1000.0000 | - | 339932.95 KB |
| CreateTempTable | 1000000 | 3,280.07 ms | NA | 110000.0000 | 1000.0000 | - | 679776.7 KB |
EntityFrameworkCore.PostgreSQL.SimpleBulks is licensed under the MIT license.