Skip to content

Commit 845c29f

Browse files
committed
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
1 parent ac2f175 commit 845c29f

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

mcp/event.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import (
2323
)
2424

2525
// If true, MemoryEventStore will do frequent validation to check invariants, slowing it down.
26-
// Remove when we're confident in the code.
27-
const validateMemoryEventStore = true
26+
// Enable for debugging.
27+
const validateMemoryEventStore = false
2828

2929
// An Event is a server-sent event.
3030
// See https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields.

mcp/event_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"slices"
1111
"strings"
1212
"testing"
13+
"time"
1314
)
1415

1516
func TestScanEvents(t *testing.T) {
@@ -252,3 +253,46 @@ func TestMemoryEventStoreAfter(t *testing.T) {
252253
})
253254
}
254255
}
256+
257+
func BenchmarkMemoryEventStore(b *testing.B) {
258+
// Benchmark with various settings for event store size, number of session,
259+
// and payload size.
260+
//
261+
// Assume a small number of streams per session, which is probably realistic.
262+
tests := []struct {
263+
name string
264+
limit int
265+
sessions int
266+
datasize int
267+
}{
268+
{"1KB", 1024, 1, 16},
269+
{"1MB", 1024 * 1024, 10, 16},
270+
{"10MB", 10 * 1024 * 1024, 100, 16},
271+
{"10MB_big", 10 * 1024 * 1024, 1000, 128},
272+
}
273+
274+
for _, test := range tests {
275+
b.Run(test.name, func(b *testing.B) {
276+
store := NewMemoryEventStore(nil)
277+
store.SetMaxBytes(test.limit)
278+
ctx := context.Background()
279+
sessionIDs := make([]string, test.sessions)
280+
streamIDs := make([][3]StreamID, test.sessions)
281+
for i := range sessionIDs {
282+
sessionIDs[i] = fmt.Sprint(i)
283+
for j := range 3 {
284+
streamIDs[i][j] = StreamID(randText())
285+
}
286+
}
287+
payload := make([]byte, test.datasize)
288+
start := time.Now()
289+
b.ResetTimer()
290+
for i := 0; i < b.N; i++ {
291+
sessionID := sessionIDs[i%len(sessionIDs)]
292+
streamID := streamIDs[i%len(sessionIDs)][i%3]
293+
store.Append(ctx, sessionID, streamID, payload)
294+
}
295+
b.ReportMetric(float64(test.datasize)*float64(b.N)/time.Since(start).Seconds(), "bytes/s")
296+
})
297+
}
298+
}

0 commit comments

Comments
 (0)