From ea9464fccd26783564e852f10212fc9ce850c5ff Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Thu, 30 Apr 2026 01:02:44 +0200 Subject: benchmark: provide a handwritten N=1 implementation for InsertAndDelete As I had expected, this removes an unfair disadvantage for Oblast, which had to maintain two differently-typed slices for Insert() and Delete(). This is not really a fair comparison since usually you would not be doing both operations in one go. For Gorp, this rewrite is neutral. But in a shocking twist, Gorm somehow does _significantly_ worse with a specialized N=1 implementation: ``` BenchmarkInsertAndDelete/N=1/via_Gorm-24 before: 11508 B/op 157 allocs/op after: 12840 B/op 172 allocs/op ``` --- benchmark/benchmark_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'benchmark/benchmark_test.go') diff --git a/benchmark/benchmark_test.go b/benchmark/benchmark_test.go index 439ecaf..12f739c 100644 --- a/benchmark/benchmark_test.go +++ b/benchmark/benchmark_test.go @@ -285,6 +285,16 @@ func BenchmarkInsertAndDelete(b *testing.B) { } must.Succeed(b, store.Delete(noctx, db, records...)) } + if batchSize == 1 { + insertAndDeleteWithOblast = func(b *testing.B) { + record := OblastEntry{Message: "hello"} + must.Succeed(b, store.Insert(noctx, db, &record)) + if record.ID == 0 { + b.Errorf("ID was not filled!") + } + must.Succeed(b, store.Delete(noctx, db, record)) + } + } insertAndDeleteWithGorp := func(b *testing.B) { records := make([]any, batchSize) @@ -299,6 +309,16 @@ func BenchmarkInsertAndDelete(b *testing.B) { } _ = must.Return(gorpDB.Delete(records...))(b) } + if batchSize == 1 { + insertAndDeleteWithGorp = func(b *testing.B) { + record := GorpEntry{Message: "hello"} + must.Succeed(b, gorpDB.Insert(&record)) + if record.ID == 0 { + b.Errorf("ID was not filled!") + } + _ = must.Return(gorpDB.Delete(&record))(b) + } + } insertAndDeleteWithGorm := func(b *testing.B) { records := make([]GormEntry, batchSize) @@ -315,6 +335,15 @@ func BenchmarkInsertAndDelete(b *testing.B) { assert.ErrEqual(b, result.Error, "") assert.Equal(b, result.RowsAffected, int64(batchSize)) } + if batchSize == 1 { + insertAndDeleteWithGorm = func(b *testing.B) { + record := GormEntry{Message: "hello"} + must.Succeed(b, gorm.G[GormEntry](gormDB).Create(b.Context(), &record)) + result := gormDB.Delete(&record) + assert.ErrEqual(b, result.Error, "") + assert.Equal(b, result.RowsAffected, 1) + } + } insertAndDeleteWithStraightExec := func(b *testing.B) { ids := make([]int64, batchSize) -- cgit v1.2.3