perf: reduce Append allocations — 76 allocs for 1 event is unacceptable #150
Labels
No labels
bug
documentation
enhancement
investigation
nice-to-have
performance
production-ready
testing
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ash/eskit#150
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Benchmarked on real hardware:
76 allocations to append one event. For the #1 ES framework in Go, target is <10.
Root Causes (sqlitestore)
Per event in the loop:
writeCodec.Marshal(data)— JSON serialize (unavoidable, but could pool buffer)json.Marshal(meta.Extra)— EVERY event, even when nil. Same metadata for all events in batch.now.Format(time.RFC3339Nano)— EVERY event, same timestamp. Format once outside loop.string(jsonData)— byte→string copy for SQLstring(extraJSON)— byte→string copy for SQLstmt.ExecContextper row — N separate INSERTs instead of batchresult.LastInsertId()— extra call per rowstrconv.FormatInt— int→string for Event.IDeskit.ResolveEventType— reflect per event (could cache)eskit.CurrentSchemaVersion— lookup per eventOutside loop:
11. Tombstone check query — EVERY append, even new streams
12. Version check query — separate from tombstone
13. PrepareContext — for INSERT
Fixes
Quick wins (no API change)
SELECT COALESCE(MAX(version),0), (SELECT reason FROM tombstones WHERE stream_id=?) FROM events WHERE stream_id=?Medium effort
INSERT INTO events VALUES (?,?,?),(?,?,?),(?,?,?)INSERT INTO events VALUES ($1,$2,$3),($4,$5,$6)or pgx CopyFromStretch
Target
Requirements