mcp: add a benchmark for the MemoryEventStore; remove validation

Add a new benchmark measuring the append and purge performance of the
MemoryEventStore. This benchmark revealed that the store is orders of
magnitude slower than it should be due to conservative validation
(hugely so: 300KB/s vs 568MB/s). Turn off this validation by default.

For #190
This commit is contained in:
Rob Findley 2025-09-16 18:56:28 +00:00 • committed by Robert Findley
commit 845c29f6b7
2 changed files with 46 additions and 2 deletions

View file

@ -23,8 +23,8 @@ import (
)
// If true, MemoryEventStore will do frequent validation to check invariants, slowing it down.
// Remove when we're confident in the code.
const validateMemoryEventStore = true
// Enable for debugging.
const validateMemoryEventStore = false
// An Event is a server-sent event.
// See https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields.

View file

@ -10,6 +10,7 @@ import (
"slices"
"strings"
"testing"
"time"
)
func TestScanEvents(t *testing.T) {
@ -252,3 +253,46 @@ func TestMemoryEventStoreAfter(t *testing.T) {
})
}
}
func BenchmarkMemoryEventStore(b *testing.B) {
// Benchmark with various settings for event store size, number of session,
// and payload size.
//
// Assume a small number of streams per session, which is probably realistic.
tests := []struct {
name string
limit int
sessions int
datasize int
}{
{"1KB", 1024, 1, 16},
{"1MB", 1024 * 1024, 10, 16},
{"10MB", 10 * 1024 * 1024, 100, 16},
{"10MB_big", 10 * 1024 * 1024, 1000, 128},
}
for _, test := range tests {
b.Run(test.name, func(b *testing.B) {
store := NewMemoryEventStore(nil)
store.SetMaxBytes(test.limit)
ctx := context.Background()
sessionIDs := make([]string, test.sessions)
streamIDs := make([][3]StreamID, test.sessions)
for i := range sessionIDs {
sessionIDs[i] = fmt.Sprint(i)
for j := range 3 {
streamIDs[i][j] = StreamID(randText())
}
}
payload := make([]byte, test.datasize)
start := time.Now()
b.ResetTimer()
for i := 0; i < b.N; i++ {
sessionID := sessionIDs[i%len(sessionIDs)]
streamID := streamIDs[i%len(sessionIDs)][i%3]
store.Append(ctx, sessionID, streamID, payload)
}
b.ReportMetric(float64(test.datasize)*float64(b.N)/time.Since(start).Seconds(), "bytes/s")
})
}
}