From ceebe145dec86a2dea59223b917927270c0b05e0 Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 18:37:14 +0800 Subject: [PATCH 1/8] test(memory): add corpus scaling benchmarks Measure local lookup, keyword and hybrid recall, diff, semantic candidates, bounded graph traversal, and atomic insert batches at 1, 10, 100, 1000, and 10000 insights. Fixtures keep vector dimensions, content length, limits, and graph degree fixed and exclude providers and setup from timings. --- internal/memory/performance_test.go | 172 ++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 internal/memory/performance_test.go diff --git a/internal/memory/performance_test.go b/internal/memory/performance_test.go new file mode 100644 index 00000000..c0037a89 --- /dev/null +++ b/internal/memory/performance_test.go @@ -0,0 +1,172 @@ +package memory_test + +import ( + "fmt" + "testing" + "time" + + "github.com/mnemon-dev/mnemon/internal/memory/embed" + "github.com/mnemon-dev/mnemon/internal/memory/graph" + "github.com/mnemon-dev/mnemon/internal/memory/model" + "github.com/mnemon-dev/mnemon/internal/memory/search" + "github.com/mnemon-dev/mnemon/internal/memory/store" +) + +// N is the number of active insights, not the benchmark iteration count. Keep +// text length, vector dimension, result limits and graph degree fixed as N grows. +var corpusSizes = []int{1, 10, 100, 1000, 10000} + +func corpusInsight(i int) *model.Insight { + created := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(i) * time.Second) + return &model.Insight{ + ID: fmt.Sprintf("ins-%06d", i), + Content: fmt.Sprintf("SQLite memory retrieval stores project record %06d with graph links and multilingual 查询性能", i), + Category: model.CategoryFact, Importance: 1 + i%5, + Tags: []string{"memory", "performance"}, Entities: []string{"SQLite", fmt.Sprintf("Project%02d", i%10)}, + Source: fmt.Sprintf("source-%02d", i%10), CreatedAt: created, UpdatedAt: created, + } +} + +func corpusVector(i int) []float64 { + v := make([]float64, 128) + for j := range v { + // Deterministic, positive vectors with varied cosine scores. Round-trip + // through the storage format so cached and stored vectors are identical. + v[j] = float64(1+(i*31+j*17)%101) / 101 + } + return embed.DeserializeVector(embed.SerializeVector(v)) +} + +type memoryCorpus struct { + db *store.DB + insights []*model.Insight + vectors graph.EmbedCache + embedded []search.EmbeddedItem +} + +func newMemoryCorpus(b *testing.B, n int) memoryCorpus { + b.Helper() + db, err := store.Open(b.TempDir()) + if err != nil { + b.Fatal(err) + } + b.Cleanup(func() { db.Close() }) + c := memoryCorpus{db: db, vectors: make(graph.EmbedCache, n)} + err = db.InTransaction(func() error { + for i := 0; i < n; i++ { + ins := corpusInsight(i) + if err := db.InsertInsight(ins); err != nil { + return err + } + vec := corpusVector(i) + if err := db.UpdateEmbedding(ins.ID, embed.SerializeVector(vec)); err != nil { + return err + } + c.insights = append(c.insights, ins) + c.vectors[ins.ID] = vec + c.embedded = append(c.embedded, search.EmbeddedItem{ID: ins.ID, Embedding: vec}) + if i > 0 { + if err := db.InsertEdge(&model.Edge{ + SourceID: c.insights[i-1].ID, TargetID: ins.ID, + EdgeType: model.EdgeCausal, Weight: 0.5, CreatedAt: ins.CreatedAt, + }); err != nil { + return err + } + } + } + return nil + }) + if err != nil { + b.Fatal(err) + } + return c +} + +// BenchmarkMemoryRead measures both pure ranking and complete local read paths. +// Setup/migration, embedding providers, access-count writes and CLI startup are +// excluded. SQLite uses a real temporary WAL database, with the default indexes. +func BenchmarkMemoryRead(b *testing.B) { + for _, n := range corpusSizes { + b.Run(fmt.Sprintf("N=%d", n), func(b *testing.B) { + c := newMemoryCorpus(b, n) + query := "SQLite memory retrieval 查询性能" + queryVec := corpusVector(7) + cases := []struct { + name string + run func() error + }{ + {"ByID", func() error { _, err := c.db.GetInsightByID(c.insights[n/2].ID); return err }}, + {"AllActive", func() error { _, err := c.db.GetAllActiveInsights(); return err }}, + {"Ranked", func() error { _, err := c.db.QueryInsights(store.QueryFilter{Limit: 10}); return err }}, + {"SourceLatest", func() error { _, err := c.db.GetLatestInsightBySource("source-00", ""); return err }}, + {"SourceRecent", func() error { _, err := c.db.GetRecentInsightsBySource("source-00", "", 10); return err }}, + {"Entity", func() error { _, err := c.db.FindInsightsWithEntity("SQLite", "", 10); return err }}, + {"Embeddings", func() error { _, err := c.db.GetAllEmbeddings(); return err }}, + {"Keyword", func() error { search.KeywordSearch(c.insights, query, 10); return nil }}, + {"Diff", func() error { + search.Diff(c.insights, query, search.DiffOptions{Limit: 5, NewEmbedding: queryVec, ExistingEmbed: c.embedded}) + return nil + }}, + {"RecallKeyword", func() error { + _, err := search.IntentAwareRecall(c.db, query, nil, []string{"SQLite"}, 10, nil) + return err + }}, + {"RecallHybrid", func() error { + _, err := search.IntentAwareRecall(c.db, query, queryVec, []string{"SQLite"}, 10, nil) + return err + }}, + {"RecallWhy", func() error { + intent := search.IntentWhy + _, err := search.IntentAwareRecall(c.db, query, queryVec, nil, 10, &intent) + return err + }}, + {"SemanticEmbedding", func() error { graph.FindSemanticCandidates(c.db, c.insights[0], c.vectors); return nil }}, + {"SemanticTokens", func() error { graph.FindSemanticCandidates(c.db, c.insights[0], graph.EmbedCache{}); return nil }}, + {"Neighborhood", func() error { graph.GetNeighborhood(c.db, c.insights[0].ID, 2, 20); return nil }}, + } + for _, tc := range cases { + b.Run(tc.name, func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + if err := tc.run(); err != nil { + b.Fatal(err) + } + } + }) + } + }) + } +} + +// BenchmarkMemoryInsert measures an atomic batch of N inserts including commit. +// Cleanup is outside the timer; each iteration inserts into the same empty store. +func BenchmarkMemoryInsert(b *testing.B) { + for _, n := range corpusSizes { + b.Run(fmt.Sprintf("N=%d", n), func(b *testing.B) { + c := newMemoryCorpus(b, 0) + insights := make([]*model.Insight, n) + for i := range insights { + insights[i] = corpusInsight(i) + } + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := c.db.InTransaction(func() error { + for _, ins := range insights { + if err := c.db.InsertInsight(ins); err != nil { + return err + } + } + return nil + }); err != nil { + b.Fatal(err) + } + b.StopTimer() + if _, err := c.db.Conn().Exec(`DELETE FROM insights`); err != nil { + b.Fatal(err) + } + b.StartTimer() + } + }) + } +} From a21d783b4cff29157c9f6257e621b4bb5e953fd1 Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 18:55:21 +0800 Subject: [PATCH 2/8] test(memory): measure CPU work and graph maintenance scaling Extend the corpus benchmarks with dense graphs, metadata scans, retention refresh, entity-provided writes, and unsuccessful filtered lookups. Report process CPU time on Darwin and Linux alongside wall time and allocation metrics so scheduler contention does not masquerade as an algorithm change. --- internal/memory/performance_cpu_other_test.go | 8 ++ internal/memory/performance_cpu_unix_test.go | 21 +++++ internal/memory/performance_test.go | 89 +++++++++++++++++-- 3 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 internal/memory/performance_cpu_other_test.go create mode 100644 internal/memory/performance_cpu_unix_test.go diff --git a/internal/memory/performance_cpu_other_test.go b/internal/memory/performance_cpu_other_test.go new file mode 100644 index 00000000..e1a80393 --- /dev/null +++ b/internal/memory/performance_cpu_other_test.go @@ -0,0 +1,8 @@ +//go:build !darwin && !linux + +package memory_test + +import "time" + +// The portable benchmarks still report wall time and allocations elsewhere. +func processCPUTime() time.Duration { return 0 } diff --git a/internal/memory/performance_cpu_unix_test.go b/internal/memory/performance_cpu_unix_test.go new file mode 100644 index 00000000..f27bb205 --- /dev/null +++ b/internal/memory/performance_cpu_unix_test.go @@ -0,0 +1,21 @@ +//go:build darwin || linux + +package memory_test + +import ( + "time" + + "golang.org/x/sys/unix" +) + +// Process CPU time distinguishes algorithm work from descheduling on a shared +// developer machine. It includes user/system time and GC, but not time blocked +// on disk. This metric complements (and never replaces) ns/op wall time. +func processCPUTime() time.Duration { + var usage unix.Rusage + if err := unix.Getrusage(unix.RUSAGE_SELF, &usage); err != nil { + return 0 + } + return time.Duration(usage.Utime.Sec+usage.Stime.Sec)*time.Second + + time.Duration(usage.Utime.Usec+usage.Stime.Usec)*time.Microsecond +} diff --git a/internal/memory/performance_test.go b/internal/memory/performance_test.go index c0037a89..a5ed64db 100644 --- a/internal/memory/performance_test.go +++ b/internal/memory/performance_test.go @@ -44,6 +44,23 @@ type memoryCorpus struct { embedded []search.EmbeddedItem } +func benchmarkMemoryOperation(b *testing.B, run func() error) { + b.Helper() + cpuStart := processCPUTime() + for b.Loop() { + if err := run(); err != nil { + b.Fatal(err) + } + } + reportCPU(b, processCPUTime()-cpuStart) +} + +func reportCPU(b *testing.B, elapsed time.Duration) { + if elapsed > 0 && b.N > 0 { + b.ReportMetric(float64(elapsed)/float64(b.N), "cpu-ns/op") + } +} + func newMemoryCorpus(b *testing.B, n int) memoryCorpus { b.Helper() db, err := store.Open(b.TempDir()) @@ -101,6 +118,11 @@ func BenchmarkMemoryRead(b *testing.B) { {"SourceLatest", func() error { _, err := c.db.GetLatestInsightBySource("source-00", ""); return err }}, {"SourceRecent", func() error { _, err := c.db.GetRecentInsightsBySource("source-00", "", 10); return err }}, {"Entity", func() error { _, err := c.db.FindInsightsWithEntity("SQLite", "", 10); return err }}, + {"EntityMiss", func() error { _, err := c.db.FindInsightsWithEntity("absent", "", 10); return err }}, + {"RankedKeywordMiss", func() error { + _, err := c.db.QueryInsights(store.QueryFilter{Keyword: "absent", Limit: 10}) + return err + }}, {"Embeddings", func() error { _, err := c.db.GetAllEmbeddings(); return err }}, {"Keyword", func() error { search.KeywordSearch(c.insights, query, 10); return nil }}, {"Diff", func() error { @@ -127,11 +149,7 @@ func BenchmarkMemoryRead(b *testing.B) { for _, tc := range cases { b.Run(tc.name, func(b *testing.B) { b.ReportAllocs() - for b.Loop() { - if err := tc.run(); err != nil { - b.Fatal(err) - } - } + benchmarkMemoryOperation(b, tc.run) }) } }) @@ -150,7 +168,9 @@ func BenchmarkMemoryInsert(b *testing.B) { } b.ReportAllocs() b.ResetTimer() + var cpuTotal time.Duration for i := 0; i < b.N; i++ { + cpuStart := processCPUTime() if err := c.db.InTransaction(func() error { for _, ins := range insights { if err := c.db.InsertInsight(ins); err != nil { @@ -161,12 +181,71 @@ func BenchmarkMemoryInsert(b *testing.B) { }); err != nil { b.Fatal(err) } + cpuTotal += processCPUTime() - cpuStart b.StopTimer() if _, err := c.db.Conn().Exec(`DELETE FROM insights`); err != nil { b.Fatal(err) } b.StartTimer() } + reportCPU(b, cpuTotal) + }) + } +} + +// BenchmarkMemoryMaintenance isolates store-wide metadata scans and the local +// graph write pipeline. Existing edges are replaced on each iteration, keeping +// the corpus size bounded; these are not provider or CLI benchmarks. +func BenchmarkMemoryMaintenance(b *testing.B) { + for _, n := range corpusSizes { + b.Run(fmt.Sprintf("N=%d", n), func(b *testing.B) { + c := newMemoryCorpus(b, n) + b.Run("KnownEntities", func(b *testing.B) { + benchmarkMemoryOperation(b, func() error { _, err := c.db.LoadKnownEntities(); return err }) + }) + b.Run("Retention", func(b *testing.B) { + benchmarkMemoryOperation(b, func() error { _, _, err := c.db.GetRetentionCandidates(1, 10); return err }) + }) + b.Run("EngineProvided", func(b *testing.B) { + engine := graph.NewEngineWithEntityMode(c.db, c.vectors, graph.EntityModeProvided) + benchmarkMemoryOperation(b, func() error { + return c.db.InTransaction(func() error { + engine.OnInsightCreated(c.insights[0]) + return nil + }) + }) + }) + }) + } +} + +func BenchmarkMemoryDenseRecall(b *testing.B) { + for _, n := range []int{1, 10, 100} { + b.Run(fmt.Sprintf("N=%d", n), func(b *testing.B) { + c := newMemoryCorpus(b, n) + if err := c.db.InTransaction(func() error { + for i, source := range c.insights { + for j, target := range c.insights { + if i == j { + continue + } + if err := c.db.InsertEdge(&model.Edge{ + SourceID: source.ID, TargetID: target.ID, EdgeType: model.EdgeSemantic, + Weight: float64(1+(i*31+j*17)%101) / 101, CreatedAt: source.CreatedAt, + }); err != nil { + return err + } + } + } + return nil + }); err != nil { + b.Fatal(err) + } + queryVec := corpusVector(7) + benchmarkMemoryOperation(b, func() error { + _, err := search.IntentAwareRecall(c.db, "SQLite memory", queryVec, nil, 10, nil) + return err + }) }) } } From 16bfe05f041c7dac3534e6cc7addd3d5c40d1757 Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 18:55:21 +0800 Subject: [PATCH 3/8] refactor(memory): index bounded reads and graph neighborhoods Replace three single-column insight indexes with active ordering indexes, avoiding full sorts for ranked and source reads without adding redundant write indexes. Read bounded BFS neighborhoods through endpoint indexes while preserving insertion order, filtering and limits; keep bulk loading for unlimited traversals. Skip known-entity scans when entities are explicitly provided. Validated query plans, index upgrades and repeated opens, bounded/bulk traversal parity, make test, Memory race tests, and all 258 CLI E2E assertions. --- internal/memory/graph/bfs.go | 86 ++++++++++---- internal/memory/graph/bfs_parity_test.go | 58 +++++++++ internal/memory/graph/engine.go | 5 +- internal/memory/store/db.go | 13 ++- internal/memory/store/edge.go | 38 ++++++ internal/memory/store/read_index_test.go | 142 +++++++++++++++++++++++ 6 files changed, 318 insertions(+), 24 deletions(-) create mode 100644 internal/memory/graph/bfs_parity_test.go create mode 100644 internal/memory/store/read_index_test.go diff --git a/internal/memory/graph/bfs.go b/internal/memory/graph/bfs.go index 28715d44..54ec4174 100644 --- a/internal/memory/graph/bfs.go +++ b/internal/memory/graph/bfs.go @@ -1,6 +1,8 @@ package graph import ( + "database/sql" + "errors" "github.com/mnemon-dev/mnemon/internal/memory/model" "github.com/mnemon-dev/mnemon/internal/memory/store" ) @@ -19,30 +21,18 @@ type BFSOptions struct { EdgeFilter model.EdgeType // filter by edge type (empty = all types) } -// BFS performs breadth-first traversal from startID over the full graph. -// Pre-loads all active insights and edges to avoid N+1 queries. -// The start node is excluded from results. Only active (non-deleted) nodes are visited. +// BFS performs breadth-first traversal. Bounded neighborhoods use indexed +// reads so disconnected history is not loaded. Unlimited traversals preload the +// graph to avoid a query per node. Both paths preserve edge insertion order. +// The start node is excluded. Only active (non-deleted) nodes are visited. func BFS(db *store.DB, startID string, opts BFSOptions) []BFSNode { - allInsights, err := db.GetAllActiveInsights() - if err != nil { + if opts.MaxDepth <= 0 { return nil } - insightMap := make(map[string]*model.Insight, len(allInsights)) - for _, ins := range allInsights { - insightMap[ins.ID] = ins - } - - allEdges, err := db.GetAllEdges() + view, err := newBFSView(db, opts) if err != nil { return nil } - edgeAdj := make(map[string][]*model.Edge) - for _, e := range allEdges { - edgeAdj[e.SourceID] = append(edgeAdj[e.SourceID], e) - if e.SourceID != e.TargetID { - edgeAdj[e.TargetID] = append(edgeAdj[e.TargetID], e) - } - } type entry struct { id string @@ -65,7 +55,11 @@ func BFS(db *store.DB, startID string, opts BFSOptions) []BFSNode { continue } - for _, edge := range edgeAdj[cur.id] { + edges, err := view.edgesFor(cur.id, opts.EdgeFilter) + if err != nil { + return nil + } + for _, edge := range edges { if opts.EdgeFilter != "" && edge.EdgeType != opts.EdgeFilter { continue } @@ -80,7 +74,10 @@ func BFS(db *store.DB, startID string, opts BFSOptions) []BFSNode { } visited[neighborID] = true - insight := insightMap[neighborID] + insight, err := view.insightFor(neighborID) + if err != nil && !errors.Is(err, sql.ErrNoRows) { + return nil + } if insight == nil { continue // soft-deleted or missing } @@ -104,3 +101,52 @@ func BFS(db *store.DB, startID string, opts BFSOptions) []BFSNode { return result } + +// bfsView owns either the bulk snapshot or indexed reads for this traversal. +// It never retains state between requests or starts background work. +type bfsView struct { + db *store.DB + insights map[string]*model.Insight + adj map[string][]*model.Edge +} + +func newBFSView(db *store.DB, opts BFSOptions) (*bfsView, error) { + v := &bfsView{db: db} + if opts.MaxNodes > 0 { + return v, nil + } + all, err := db.GetAllActiveInsights() + if err != nil { + return nil, err + } + v.insights = make(map[string]*model.Insight, len(all)) + for _, ins := range all { + v.insights[ins.ID] = ins + } + edges, err := db.GetAllEdges() + if err != nil { + return nil, err + } + v.adj = make(map[string][]*model.Edge) + for _, edge := range edges { + v.adj[edge.SourceID] = append(v.adj[edge.SourceID], edge) + if edge.SourceID != edge.TargetID { + v.adj[edge.TargetID] = append(v.adj[edge.TargetID], edge) + } + } + return v, nil +} + +func (v *bfsView) edgesFor(id string, edgeType model.EdgeType) ([]*model.Edge, error) { + if v.adj != nil { + return v.adj[id], nil + } + return v.db.GetTraversalEdges(id, edgeType) +} + +func (v *bfsView) insightFor(id string) (*model.Insight, error) { + if v.insights != nil { + return v.insights[id], nil + } + return v.db.GetInsightByID(id) +} diff --git a/internal/memory/graph/bfs_parity_test.go b/internal/memory/graph/bfs_parity_test.go new file mode 100644 index 00000000..b237f1ad --- /dev/null +++ b/internal/memory/graph/bfs_parity_test.go @@ -0,0 +1,58 @@ +package graph + +import ( + "fmt" + "github.com/mnemon-dev/mnemon/internal/memory/model" + "math/rand" + "reflect" + "testing" + "time" +) + +func TestBoundedBFSMatchesBulkTraversal(t *testing.T) { + db := testDB(t) + now := time.Now().UTC() + for i := 0; i < 30; i++ { + id := fmt.Sprintf("n-%02d", i) + insertInsight(t, db, id, id, "test", 3, nil, now) + } + rng := rand.New(rand.NewSource(29)) + types := []model.EdgeType{model.EdgeSemantic, model.EdgeTemporal, model.EdgeCausal, model.EdgeEntity} + for range 150 { + e := &model.Edge{ + SourceID: fmt.Sprintf("n-%02d", rng.Intn(30)), TargetID: fmt.Sprintf("n-%02d", rng.Intn(30)), + EdgeType: types[rng.Intn(len(types))], Weight: 0.5, CreatedAt: now, + } + if err := db.InsertEdge(e); err != nil { + t.Fatal(err) + } + } + // Real recovered stores can contain both deleted and missing endpoints. + // Leave their incident edges in place and ensure neither traversal returns them. + if _, err := db.Conn().Exec(`UPDATE insights SET deleted_at = ? WHERE id = 'n-29'`, now.Format(time.RFC3339)); err != nil { + t.Fatal(err) + } + if _, err := db.Conn().Exec(`PRAGMA foreign_keys = OFF`); err != nil { + t.Fatal(err) + } + if _, err := db.Conn().Exec(`DELETE FROM insights WHERE id = 'n-28'`); err != nil { + t.Fatal(err) + } + if _, err := db.Conn().Exec(`PRAGMA foreign_keys = ON`); err != nil { + t.Fatal(err) + } + for _, filter := range append(types, "") { + for _, depth := range []int{0, 1, 2, 4} { + for _, start := range []string{"n-00", "n-10", "missing"} { + full := BFS(db, start, BFSOptions{MaxDepth: depth, EdgeFilter: filter}) + for _, limit := range []int{1, 3, 10, 100} { + got := BFS(db, start, BFSOptions{MaxDepth: depth, MaxNodes: limit, EdgeFilter: filter}) + want := full[:min(limit, len(full))] + if !reflect.DeepEqual(got, want) { + t.Fatalf("start=%s filter=%s depth=%d limit=%d: indexed traversal differs from bulk", start, filter, depth, limit) + } + } + } + } + } +} diff --git a/internal/memory/graph/engine.go b/internal/memory/graph/engine.go index 8080ce2f..3bfc4719 100644 --- a/internal/memory/graph/engine.go +++ b/internal/memory/graph/engine.go @@ -72,7 +72,10 @@ func (e *Engine) OnInsightCreated(insight *model.Insight) EdgeStats { // the graph propagates into new insights without dictionary edits. On // error the index lookup falls through to nil and behavior matches the // non-indexed extractor. - knownEntities, _ := e.db.LoadKnownEntities() + var knownEntities map[string]bool + if e.entityMode != EntityModeProvided { + knownEntities, _ = e.db.LoadKnownEntities() + } insight.Entities = ResolveEntitiesIndexed(insight.Content, insight.Entities, e.entityMode, knownEntities) // 2. Temporal backbone + proximity edges diff --git a/internal/memory/store/db.go b/internal/memory/store/db.go index 9cb57b99..bd2d33aa 100644 --- a/internal/memory/store/db.go +++ b/internal/memory/store/db.go @@ -308,10 +308,17 @@ CREATE TABLE IF NOT EXISTS edges ( ); CREATE INDEX IF NOT EXISTS idx_insights_category ON insights(category); -CREATE INDEX IF NOT EXISTS idx_insights_importance ON insights(importance); -CREATE INDEX IF NOT EXISTS idx_insights_created ON insights(created_at); CREATE INDEX IF NOT EXISTS idx_insights_deleted ON insights(deleted_at); -CREATE INDEX IF NOT EXISTS idx_insights_source ON insights(source); +-- Match active read paths without sorting every matching row before LIMIT. +CREATE INDEX IF NOT EXISTS idx_insights_active_created ON insights(deleted_at, created_at DESC) WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_insights_active_source_created ON insights(source, created_at) WHERE deleted_at IS NULL; +CREATE INDEX IF NOT EXISTS idx_insights_active_ranked ON insights(deleted_at, importance DESC, created_at DESC) WHERE deleted_at IS NULL; +-- The active composite indexes replace these single-column read indexes; do +-- not make every insert maintain both versions. Keep the deleted index for +-- counts that include deleted history. +DROP INDEX IF EXISTS idx_insights_importance; +DROP INDEX IF EXISTS idx_insights_created; +DROP INDEX IF EXISTS idx_insights_source; CREATE INDEX IF NOT EXISTS idx_edges_source ON edges(source_id); CREATE INDEX IF NOT EXISTS idx_edges_target ON edges(target_id); CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(edge_type); diff --git a/internal/memory/store/edge.go b/internal/memory/store/edge.go index 8dca1aa8..81a1a50c 100644 --- a/internal/memory/store/edge.go +++ b/internal/memory/store/edge.go @@ -39,6 +39,44 @@ func (db *DB) GetEdgesByNode(nodeID string) ([]*model.Edge, error) { return scanEdges(rows) } +// GetTraversalEdges returns incident edges in insertion order, optionally +// filtered by type. BFS previously obtained this order by scanning the entire +// edges table; preserving it matters when a node limit cuts a frontier. +func (db *DB) GetTraversalEdges(nodeID string, edgeType model.EdgeType) ([]*model.Edge, error) { + query, args := traversalEdgeQuery(nodeID, edgeType) + rows, err := db.execer().Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + edges, err := scanEdges(rows) + if err != nil { + return nil, err + } + return edges, rows.Err() +} + +func traversalEdgeQuery(nodeID string, edgeType model.EdgeType) (string, []any) { + const columns = "source_id, target_id, edge_type, weight, metadata, created_at" + source := "SELECT rowid AS edge_order, " + columns + " FROM edges WHERE source_id = ?" + target := "SELECT rowid AS edge_order, " + columns + " FROM edges WHERE target_id = ? AND source_id != ?" + args := []any{nodeID} + if edgeType != "" { + source += " AND edge_type = ?" + target += " AND edge_type = ?" + args = append(args, string(edgeType)) + } + args = append(args, nodeID, nodeID) + if edgeType != "" { + args = append(args, string(edgeType)) + } + // UNION keeps each endpoint lookup on its own composite index. A factored + // OR with an edge_type filter can instead scan every edge of that type. + // Excluding self-loops from the target branch returns each edge only once. + query := "SELECT " + columns + " FROM (" + source + " UNION ALL " + target + ") ORDER BY edge_order" + return query, args +} + // supersededLookupChunk bounds how many ids go into one IN clause. SQLite's // host-parameter ceiling is 32766 on current builds and 999 on older ones; // 500 stays inside both. Recall's candidate set is normally far smaller, so diff --git a/internal/memory/store/read_index_test.go b/internal/memory/store/read_index_test.go new file mode 100644 index 00000000..7e9cc9a1 --- /dev/null +++ b/internal/memory/store/read_index_test.go @@ -0,0 +1,142 @@ +package store + +import ( + "fmt" + "strings" + "testing" + "time" + + "github.com/mnemon-dev/mnemon/internal/memory/model" +) + +func TestActiveReadPlansAvoidFullSort(t *testing.T) { + db := testDB(t) + const columns = `id, content, category, importance, tags, entities, source, + access_count, created_at, updated_at, deleted_at` + cases := []struct { + name, where, order string + args []any + }{ + {"all", `deleted_at IS NULL`, `created_at DESC`, nil}, + {"ranked", `deleted_at IS NULL`, `importance DESC, created_at DESC LIMIT 10`, nil}, + {"latest", `source = ? AND id != ? AND deleted_at IS NULL`, `created_at DESC, rowid DESC LIMIT 1`, []any{"s", ""}}, + {"recent", `source = ? AND id != ? AND deleted_at IS NULL`, `created_at DESC LIMIT 10`, []any{"s", ""}}, + {"window", `id != ? AND deleted_at IS NULL AND created_at >= ?`, `created_at DESC LIMIT 10`, []any{"", "2026-01-01"}}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + query := fmt.Sprintf("EXPLAIN QUERY PLAN SELECT %s FROM insights WHERE %s ORDER BY %s", columns, tc.where, tc.order) + rows, err := db.Conn().Query(query, tc.args...) + if err != nil { + t.Fatal(err) + } + defer rows.Close() + for rows.Next() { + var id, parent, unused int + var detail string + if err := rows.Scan(&id, &parent, &unused, &detail); err != nil { + t.Fatal(err) + } + t.Log(detail) + if strings.Contains(detail, "TEMP B-TREE") { + t.Errorf("active ordered read still sorts rows: %s", detail) + } + } + if err := rows.Err(); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestActiveReadIndexesReopenAndDeletedRows(t *testing.T) { + dir := t.TempDir() + db, err := Open(dir) + if err != nil { + t.Fatal(err) + } + // Recreate the pre-index schema before reopening to exercise an upgrade. + for _, index := range []string{"idx_insights_active_created", "idx_insights_active_source_created", "idx_insights_active_ranked"} { + if _, err := db.Conn().Exec("DROP INDEX " + index); err != nil { + t.Fatal(err) + } + } + for _, column := range []string{"importance", "created_at", "source"} { + name := strings.TrimSuffix(column, "_at") + if _, err := db.Conn().Exec(fmt.Sprintf("CREATE INDEX idx_insights_%s ON insights(%s)", name, column)); err != nil { + t.Fatal(err) + } + } + now := time.Now().UTC().Truncate(time.Second) + for i, id := range []string{"first", "second", "deleted"} { + ins := makeInsight(id, "indexed read", 3+i) + ins.CreatedAt = now + if err := db.InsertInsight(ins); err != nil { + t.Fatal(err) + } + } + if err := db.SoftDeleteInsight("deleted"); err != nil { + t.Fatal(err) + } + if err := db.Close(); err != nil { + t.Fatal(err) + } + for range 2 { // also exercise idempotent migration + db, err = Open(dir) + if err != nil { + t.Fatal(err) + } + var redundant int + if err := db.Conn().QueryRow(`SELECT COUNT(*) FROM sqlite_master WHERE type = 'index' + AND name IN ('idx_insights_importance', 'idx_insights_created', 'idx_insights_source')`).Scan(&redundant); err != nil { + t.Fatal(err) + } + if redundant != 0 { + t.Fatal("upgrade kept redundant write indexes") + } + latest, err := db.GetLatestInsightBySource("test", "") + if err != nil || latest.ID != "second" { + t.Fatalf("latest = %v, err = %v", latest, err) + } + excluded, err := db.GetLatestInsightBySource("test", "second") + if err != nil || excluded.ID != "first" { + t.Fatalf("excluded = %v, err = %v", excluded, err) + } + ranked, err := db.QueryInsights(QueryFilter{Limit: 1}) + if err != nil || len(ranked) != 1 || ranked[0].ID != "second" { + t.Fatalf("ranked = %v, err = %v", ranked, err) + } + if err := db.Close(); err != nil { + t.Fatal(err) + } + } +} + +func TestTraversalReadPlansUseEndpointIndexes(t *testing.T) { + db := testDB(t) + for _, filter := range []model.EdgeType{"", model.EdgeCausal} { + query, args := traversalEdgeQuery("a", filter) + rows, err := db.Conn().Query("EXPLAIN QUERY PLAN "+query, args...) + if err != nil { + t.Fatal(err) + } + var plan []string + for rows.Next() { + var id, parent, unused int + var detail string + if err := rows.Scan(&id, &parent, &unused, &detail); err != nil { + t.Fatal(err) + } + plan = append(plan, detail) + } + if err := rows.Err(); err != nil { + t.Fatal(err) + } + rows.Close() + joined := strings.Join(plan, "\n") + t.Log(joined) + if !strings.Contains(joined, "source_id=?") || !strings.Contains(joined, "target_id=?") { + t.Errorf("traversal reads unrelated edges with filter %q: %s", filter, joined) + } + } +} From 8c3da78f7838855fb31fc785b824bb4cf1e63469 Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 18:55:31 +0800 Subject: [PATCH 4/8] refactor(memory): reuse recall signals and bound candidate selection Keep query-local scalar keyword and cosine scores, reuse active insight hydration and adjacency reads across anchors, and stream embeddings without retaining every vector. Reuse ordered time anchors after checking absolute timestamps. Select semantic and embedding-only diff candidates with one bounded typed heap and tokenize repeated query text only once. Preserve scoring weights, thresholds, traversal budgets, supersession demotion and provider fallbacks. Characterization tests compare cached traversal against the prior algorithm across all intents and budgets, check query refresh and timestamp offsets, and enforce the top-K comparison bound. make test, Memory race tests and all 258 CLI E2E assertions passed. --- Makefile | 1 + internal/memory/graph/semantic.go | 87 +++------ internal/memory/graph/semantic_topk_test.go | 38 ++++ internal/memory/internal/topk/topk.go | 63 +++++++ internal/memory/internal/topk/topk_test.go | 70 ++++++++ internal/memory/search/diff.go | 13 +- internal/memory/search/integration_test.go | 9 +- internal/memory/search/keyword.go | 42 +++-- internal/memory/search/recall.go | 149 +++++----------- internal/memory/search/recall_cache.go | 57 ++++++ internal/memory/search/recall_cache_test.go | 165 ++++++++++++++++++ .../memory/search/recall_reference_test.go | 109 ++++++++++++ internal/memory/store/node.go | 2 +- .../architecture/mnemond_structure_test.go | 13 +- 14 files changed, 615 insertions(+), 203 deletions(-) create mode 100644 internal/memory/graph/semantic_topk_test.go create mode 100644 internal/memory/internal/topk/topk.go create mode 100644 internal/memory/internal/topk/topk_test.go create mode 100644 internal/memory/search/recall_cache.go create mode 100644 internal/memory/search/recall_cache_test.go create mode 100644 internal/memory/search/recall_reference_test.go diff --git a/Makefile b/Makefile index 44b3a8c9..cc953bc2 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ DETERMINISTIC_PKGS := \ ./internal/memory/embed \ ./internal/memory/graph \ ./internal/memory/importdraft \ + ./internal/memory/internal/topk \ ./internal/memory/model \ ./internal/memory/search \ ./internal/memory/setup \ diff --git a/internal/memory/graph/semantic.go b/internal/memory/graph/semantic.go index 0f70bdea..74b48f7c 100644 --- a/internal/memory/graph/semantic.go +++ b/internal/memory/graph/semantic.go @@ -2,10 +2,10 @@ package graph import ( "fmt" - "sort" "time" "github.com/mnemon-dev/mnemon/internal/memory/embed" + "github.com/mnemon-dev/mnemon/internal/memory/internal/topk" "github.com/mnemon-dev/mnemon/internal/memory/model" "github.com/mnemon-dev/mnemon/internal/memory/search" "github.com/mnemon-dev/mnemon/internal/memory/store" @@ -70,32 +70,11 @@ func CreateSemanticEdges(db *store.DB, insight *model.Insight, embedCache EmbedC return 0 } - type scored struct { - id string - similarity float64 - } - var candidates []scored - for id, otherVec := range embedCache { - if id == insight.ID { - continue - } - cosSim := embed.CosineSimilarity(insightVec, otherVec) - if cosSim >= autoSemanticThreshold { - candidates = append(candidates, scored{id: id, similarity: cosSim}) - } - } - + candidates := semanticTopK(embedCache, insight.ID, insightVec, autoSemanticThreshold, maxAutoSemanticEdges) if len(candidates) == 0 { return 0 } - sort.Slice(candidates, func(i, j int) bool { - return candidates[i].similarity > candidates[j].similarity - }) - if len(candidates) > maxAutoSemanticEdges { - candidates = candidates[:maxAutoSemanticEdges] - } - now := time.Now().UTC() count := 0 for _, c := range candidates { @@ -151,34 +130,11 @@ func findCandidatesByEmbedding(db *store.DB, insight *model.Insight, embedCache return nil } - type scored struct { - id string - similarity float64 - } - - var candidates []scored - for id, otherVec := range embedCache { - if id == insight.ID { - continue - } - cosSim := embed.CosineSimilarity(insightVec, otherVec) - if cosSim >= reviewSemanticThreshold { - candidates = append(candidates, scored{id: id, similarity: cosSim}) - } - } - + candidates := semanticTopK(embedCache, insight.ID, insightVec, reviewSemanticThreshold, maxSemanticCandidates) if len(candidates) == 0 { return nil } - sort.Slice(candidates, func(i, j int) bool { - return candidates[i].similarity > candidates[j].similarity - }) - - if len(candidates) > maxSemanticCandidates { - candidates = candidates[:maxSemanticCandidates] - } - result := make([]SemanticCandidate, 0, len(candidates)) for _, c := range candidates { ins, err := db.GetInsightByID(c.id) @@ -211,24 +167,18 @@ func findCandidatesByTokenOverlap(db *store.DB, insight *model.Insight) []Semant similarity float64 } - var candidates []scored + best := topk.New(maxSemanticCandidates, func(a, b scored) bool { return a.similarity > b.similarity }) + queryTokens := search.Tokenize(insight.Content) for _, other := range all { if other.ID == insight.ID { continue } - sim := search.ContentSimilarity(insight.Content, other.Content) + sim := search.TokenOverlapSimilarity(queryTokens, search.Tokenize(other.Content)) if sim >= minSemanticSimilarity { - candidates = append(candidates, scored{insight: other, similarity: sim}) + best.Add(scored{insight: other, similarity: sim}) } } - - sort.Slice(candidates, func(i, j int) bool { - return candidates[i].similarity > candidates[j].similarity - }) - - if len(candidates) > maxSemanticCandidates { - candidates = candidates[:maxSemanticCandidates] - } + candidates := best.Sorted() result := make([]SemanticCandidate, len(candidates)) for i, c := range candidates { @@ -241,3 +191,24 @@ func findCandidatesByTokenOverlap(db *store.DB, insight *model.Insight) []Semant } return result } + +type semanticScore struct { + id string + similarity float64 +} + +// semanticTopK performs exact cosine scoring, keeping only the bounded output. +// Filtering active/missing candidates still occurs after selection, preserving +// the caller's existing fallback and edge-write behavior. +func semanticTopK(cache EmbedCache, excludeID string, vec []float64, threshold float64, limit int) []semanticScore { + best := topk.New(limit, func(a, b semanticScore) bool { return a.similarity > b.similarity }) + for id, other := range cache { + if id == excludeID { + continue + } + if sim := embed.CosineSimilarity(vec, other); sim >= threshold { + best.Add(semanticScore{id: id, similarity: sim}) + } + } + return best.Sorted() +} diff --git a/internal/memory/graph/semantic_topk_test.go b/internal/memory/graph/semantic_topk_test.go new file mode 100644 index 00000000..eebe85fb --- /dev/null +++ b/internal/memory/graph/semantic_topk_test.go @@ -0,0 +1,38 @@ +package graph + +import ( + "fmt" + "github.com/mnemon-dev/mnemon/internal/memory/embed" + "math/rand" + "reflect" + "sort" + "testing" +) + +func TestSemanticTopKMatchesFullSort(t *testing.T) { + rng := rand.New(rand.NewSource(31)) + query := []float64{1, 0, 0, 0} + cache := EmbedCache{"self": query, "zero": {0, 0, 0, 0}, "wrong-dimension": {1}} + for i := 0; i < 100; i++ { + cache[fmt.Sprintf("n-%03d", i)] = []float64{rng.Float64(), rng.Float64(), rng.Float64(), rng.Float64()} + } + for _, threshold := range []float64{reviewSemanticThreshold, autoSemanticThreshold} { + var full []semanticScore + for id, vec := range cache { + if id == "self" { + continue + } + if sim := embed.CosineSimilarity(query, vec); sim >= threshold { + full = append(full, semanticScore{id, sim}) + } + } + sort.Slice(full, func(i, j int) bool { return full[i].similarity > full[j].similarity }) + for _, limit := range []int{1, 3, 5, 1000} { + got := semanticTopK(cache, "self", query, threshold, limit) + want := full[:min(limit, len(full))] + if !reflect.DeepEqual(got, want) { + t.Fatalf("threshold=%v limit=%d: got %v want %v", threshold, limit, got, want) + } + } + } +} diff --git a/internal/memory/internal/topk/topk.go b/internal/memory/internal/topk/topk.go new file mode 100644 index 00000000..6fa30f55 --- /dev/null +++ b/internal/memory/internal/topk/topk.go @@ -0,0 +1,63 @@ +// Package topk retains a bounded set of best candidates without sorting or +// storing all matches. Callers own relevance and tie-breaking policy. +package topk + +import "sort" + +// Selector is a worst-first heap. It belongs to one synchronous selection. +type Selector[T any] struct { + items []T + limit int + better func(T, T) bool +} + +// New requires a positive limit and a strict ordering. better must be pure and +// nonblocking; equal candidates do not displace an already retained candidate. +func New[T any](limit int, better func(T, T) bool) *Selector[T] { + if limit <= 0 { + panic("topk: limit must be positive") + } + return &Selector[T]{limit: limit, better: better} +} + +// Add takes O(log K) time and keeps at most K values. Typed heap operations avoid +// boxing each candidate into container/heap's any-shaped Push/Pop interface. +func (s *Selector[T]) Add(value T) { + if len(s.items) < s.limit { + s.items = append(s.items, value) + for i := len(s.items) - 1; i > 0; { + parent := (i - 1) / 2 + if !s.better(s.items[parent], s.items[i]) { + break + } + s.items[parent], s.items[i] = s.items[i], s.items[parent] + i = parent + } + return + } + if !s.better(value, s.items[0]) { + return + } + s.items[0] = value + for i := 0; ; { + child := 2*i + 1 + if child >= len(s.items) { + break + } + if child+1 < len(s.items) && s.better(s.items[child], s.items[child+1]) { + child++ + } + if !s.better(s.items[i], s.items[child]) { + break + } + s.items[i], s.items[child] = s.items[child], s.items[i] + i = child + } +} + +// Sorted consumes the selector and returns its owned slice, best first. +// Do not call Add after Sorted. +func (s *Selector[T]) Sorted() []T { + sort.Slice(s.items, func(i, j int) bool { return s.better(s.items[i], s.items[j]) }) + return s.items +} diff --git a/internal/memory/internal/topk/topk_test.go b/internal/memory/internal/topk/topk_test.go new file mode 100644 index 00000000..2bd025f1 --- /dev/null +++ b/internal/memory/internal/topk/topk_test.go @@ -0,0 +1,70 @@ +package topk + +import ( + "math/bits" + "math/rand" + "reflect" + "sort" + "testing" +) + +func TestSelectionMatchesFullSort(t *testing.T) { + rng := rand.New(rand.NewSource(17)) + for _, n := range []int{0, 1, 10, 100, 1000} { + for _, k := range []int{1, 3, 5, 20, 1001} { + for _, ties := range []bool{false, true} { + values := rng.Perm(n) + if ties { + for i := range values { + values[i] %= 7 + } + } + s := New(k, func(a, b int) bool { return a > b }) + for _, value := range values { + s.Add(value) + } + want := append([]int(nil), values...) + sort.Sort(sort.Reverse(sort.IntSlice(want))) + want = want[:min(k, n)] + if got := s.Sorted(); !reflect.DeepEqual(got, want) { + t.Fatalf("n=%d k=%d ties=%v: got %v, want %v", n, k, ties, got, want) + } + } + } + } +} + +func TestComparisonBudget(t *testing.T) { + const k = 5 + for _, n := range []int{1, 10, 100, 1000, 10000} { + comparisons := 0 + s := New(k, func(a, b int) bool { comparisons++; return a > b }) + // Ascending input forces replacement of the root on every full-heap Add. + for i := 0; i < n; i++ { + s.Add(i) + } + s.Sorted() + budget := n*(2*bits.Len(uint(k))+1) + k*k + if comparisons > budget { + t.Fatalf("N=%d: %d comparisons exceed O(N log K) budget %d", n, comparisons, budget) + } + t.Logf("N=%d K=%d comparisons=%d", n, k, comparisons) + } +} + +func TestTiePolicyAndSmallestSelection(t *testing.T) { + type item struct{ score, id int } + better := func(a, b item) bool { + if a.score != b.score { + return a.score < b.score + } + return a.id < b.id + } + s := New(2, better) + for _, v := range []item{{3, 0}, {1, 2}, {2, 3}, {1, 1}, {1, 0}} { + s.Add(v) + } + if got, want := s.Sorted(), []item{{1, 0}, {1, 1}}; !reflect.DeepEqual(got, want) { + t.Fatalf("got %v, want %v", got, want) + } +} diff --git a/internal/memory/search/diff.go b/internal/memory/search/diff.go index 521e5098..49915328 100644 --- a/internal/memory/search/diff.go +++ b/internal/memory/search/diff.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/mnemon-dev/mnemon/internal/memory/embed" + "github.com/mnemon-dev/mnemon/internal/memory/internal/topk" "github.com/mnemon-dev/mnemon/internal/memory/model" ) @@ -109,24 +110,18 @@ func Diff(insights []*model.Insight, newContent string, opts DiffOptions) DiffRe id string sim float64 } - var topCosine []cosinePair + best := topk.New(opts.Limit, func(a, b cosinePair) bool { return a.sim > b.sim }) for _, ei := range opts.ExistingEmbed { if seen[ei.ID] { continue } cs := embed.CosineSimilarity(opts.NewEmbedding, ei.Embedding) if cs >= 0.7 { // only consider meaningfully similar items - topCosine = append(topCosine, cosinePair{ei.ID, cs}) + best.Add(cosinePair{ei.ID, cs}) } } - // Sort by cosine descending, take up to opts.Limit - sort.Slice(topCosine, func(i, j int) bool { - return topCosine[i].sim > topCosine[j].sim - }) - if len(topCosine) > opts.Limit { - topCosine = topCosine[:opts.Limit] - } + topCosine := best.Sorted() // Look up full insight for cosine-only matches insightMap := make(map[string]*model.Insight, len(insights)) diff --git a/internal/memory/search/integration_test.go b/internal/memory/search/integration_test.go index 9453db33..b6b07b05 100644 --- a/internal/memory/search/integration_test.go +++ b/internal/memory/search/integration_test.go @@ -436,13 +436,12 @@ func TestBeamSearchFromAnchor_ScorePropagation(t *testing.T) { scoreMap := make(map[string]float64) viaMap := make(map[string]string) - insightMap := make(map[string]*model.Insight) weights := GetWeights(IntentGeneral) params := TraversalParams{BeamWidth: 10, MaxDepth: 3, MaxVisited: 100} scoreMap["bs-1"] = 1.0 - beamSearchFromAnchor(db, "bs-1", 1.0, nil, weights, params, scoreMap, viaMap, insightMap, nil) + newRecallCache(db, nil, nil).beamSearchFromAnchor("bs-1", 1.0, weights, params, scoreMap, viaMap) // Neighbor should be discovered with score > 0 if _, ok := scoreMap["bs-2"]; !ok { @@ -477,14 +476,13 @@ func TestBeamSearchFromAnchor_BeamWidthPruning(t *testing.T) { scoreMap := make(map[string]float64) viaMap := make(map[string]string) - insightMap := make(map[string]*model.Insight) weights := GetWeights(IntentGeneral) // BeamWidth=3: only top 3 leaves should be expanded to the deep layer params := TraversalParams{BeamWidth: 3, MaxDepth: 3, MaxVisited: 500} scoreMap["bw-center"] = 1.0 - beamSearchFromAnchor(db, "bw-center", 1.0, nil, weights, params, scoreMap, viaMap, insightMap, nil) + newRecallCache(db, nil, nil).beamSearchFromAnchor("bw-center", 1.0, weights, params, scoreMap, viaMap) // Count deep nodes discovered — should be limited by beam width deepCount := 0 @@ -515,14 +513,13 @@ func TestBeamSearchFromAnchor_MaxVisitedBudget(t *testing.T) { scoreMap := make(map[string]float64) viaMap := make(map[string]string) - insightMap := make(map[string]*model.Insight) weights := GetWeights(IntentGeneral) // MaxVisited=5: should stop after visiting 5 nodes total (including start) params := TraversalParams{BeamWidth: 10, MaxDepth: 20, MaxVisited: 5} scoreMap["mv-0"] = 1.0 - beamSearchFromAnchor(db, "mv-0", 1.0, nil, weights, params, scoreMap, viaMap, insightMap, nil) + newRecallCache(db, nil, nil).beamSearchFromAnchor("mv-0", 1.0, weights, params, scoreMap, viaMap) // scoreMap includes the anchor itself, so discovered nodes (excluding anchor) should be <= 4 discovered := len(scoreMap) - 1 // subtract anchor diff --git a/internal/memory/search/keyword.go b/internal/memory/search/keyword.go index c9348976..84173a1a 100644 --- a/internal/memory/search/keyword.go +++ b/internal/memory/search/keyword.go @@ -41,9 +41,9 @@ func KeywordSearch(insights []*model.Insight, query string, limit int) []ScoredI return keywordSearchCached(insights, query, limit, nil) } -// keywordSearchCached is the internal implementation that optionally populates a token cache. -// If tokenCache is non-nil, it stores each insight's combined token set keyed by ID. -func keywordSearchCached(insights []*model.Insight, query string, limit int, tokenCache map[string]map[string]bool) []ScoredInsight { +// keywordSearchCached is the internal implementation that optionally retains keyword scores. +// If scoreCache is non-nil, it stores overlap scores for reranking, including zeros. +func keywordSearchCached(insights []*model.Insight, query string, limit int, scoreCache map[string]float64) []ScoredInsight { queryTokens := Tokenize(query) if len(queryTokens) == 0 { return nil @@ -52,20 +52,19 @@ func keywordSearchCached(insights []*model.Insight, query string, limit int, tok h := &scoredHeap{} for _, ins := range insights { contentTokens := insightTokens(ins) - if tokenCache != nil { - tokenCache[ins.ID] = contentTokens - } - intersection := 0 for t := range queryTokens { if contentTokens[t] { intersection++ } } + score := float64(intersection) / float64(len(queryTokens)) + if scoreCache != nil { + scoreCache[ins.ID] = score + } if intersection == 0 { continue } - score := float64(intersection) / float64(len(queryTokens)) if limit <= 0 || h.Len() < limit { heap.Push(h, ScoredInsight{Insight: ins, Score: score}) @@ -87,14 +86,10 @@ func keywordSearchCached(insights []*model.Insight, query string, limit int, tok func insightTokens(ins *model.Insight) map[string]bool { tokens := Tokenize(ins.Content) for _, tag := range ins.Tags { - for t := range Tokenize(tag) { - tokens[t] = true - } + addTokens(tokens, tag) } for _, ent := range ins.Entities { - for t := range Tokenize(ent) { - tokens[t] = true - } + addTokens(tokens, ent) } return tokens } @@ -124,13 +119,19 @@ var stopwords = map[string]bool{ // character bigrams. Common English stopwords are excluded. func Tokenize(text string) map[string]bool { tokens := make(map[string]bool) + addTokens(tokens, text) + return tokens +} + +// addTokens merges one text into an existing token set. Each field is processed +// separately so CJK bigrams never span content/tag/entity boundaries. +func addTokens(tokens map[string]bool, text string) { text = strings.ToLower(text) var word strings.Builder - runes := []rune(text) var cjkBuf []rune - for _, r := range runes { + for _, r := range text { if unicode.Is(unicode.Han, r) { if word.Len() > 0 { w := word.String() @@ -167,7 +168,6 @@ func Tokenize(text string) map[string]bool { if len(cjkBuf) > 0 { flushCJK(cjkBuf, tokens) } - return tokens } func flushCJK(buf []rune, tokens map[string]bool) { @@ -205,8 +205,12 @@ func JaccardSimilarity(a, b string) float64 { // ContentSimilarity computes bidirectional token overlap between two texts. // Returns max(overlap_a_to_b, overlap_b_to_a) for a symmetric measure. func ContentSimilarity(a, b string) float64 { - tokA := Tokenize(a) - tokB := Tokenize(b) + return TokenOverlapSimilarity(Tokenize(a), Tokenize(b)) +} + +// TokenOverlapSimilarity computes the same bidirectional overlap as +// ContentSimilarity over already-tokenized text. Neither input is modified. +func TokenOverlapSimilarity(tokA, tokB map[string]bool) float64 { if len(tokA) == 0 || len(tokB) == 0 { return 0 } diff --git a/internal/memory/search/recall.go b/internal/memory/search/recall.go index ebe70ed8..65fa5332 100644 --- a/internal/memory/search/recall.go +++ b/internal/memory/search/recall.go @@ -7,7 +7,6 @@ import ( "sort" "strings" - "github.com/mnemon-dev/mnemon/internal/memory/embed" "github.com/mnemon-dev/mnemon/internal/memory/model" "github.com/mnemon-dev/mnemon/internal/memory/store" ) @@ -149,67 +148,58 @@ func IntentAwareRecall(db *store.DB, query string, queryVec []float64, return RecallResponse{}, err } - // Pre-load all embeddings once (avoids N+1 queries in beam search and reranking). - var embedCache map[string][]float64 - if queryVec != nil { - if dbEmbeds, err := db.GetAllEmbeddings(); err == nil { - embedCache = make(map[string][]float64, len(dbEmbeds)) - for _, e := range dbEmbeds { - if v := embed.DeserializeVector(e.Embedding); v != nil { - embedCache[e.ID] = v - } - } - } - } - hasEmbeddings := embedCache != nil && len(embedCache) > 0 + // Cache only this query's scalar signals and the adjacency lists it visits. + // Full vectors and token sets need not survive their first scoring pass. + cache := newRecallCache(db, all, queryVec) + hasEmbeddings := len(cache.similarities) > 0 // Step 2: Multi-signal anchor selection via RRF type anchor struct { - insight *model.Insight - score float64 - via string + score float64 + via string } anchorMap := make(map[string]*anchor) - // Signal 1: Keyword search (populates tokenCache for reranking reuse) - tokenCache := make(map[string]map[string]bool, len(all)) - keywordAnchors := keywordSearchCached(all, query, anchorTopK, tokenCache) + // Signal 1: Keyword search (retains scalar scores for reranking) + keywordScores := make(map[string]float64, len(all)) + keywordAnchors := keywordSearchCached(all, query, anchorTopK, keywordScores) for rank, a := range keywordAnchors { anchorMap[a.Insight.ID] = &anchor{ - insight: a.Insight, - score: 1.0 / float64(rrfK+rank+1), - via: "keyword", + score: 1.0 / float64(rrfK+rank+1), + via: "keyword", } } // Signal 2: Vector search (when available, uses pre-loaded cache) if hasEmbeddings { - vectorHits := vectorSearchFromCache(embedCache, queryVec, anchorTopK) + vectorHits := vectorSearchFromScores(cache.similarities, anchorTopK) for rank, vh := range vectorHits { rrfScore := 1.0 / float64(rrfK+rank+1) if existing, ok := anchorMap[vh.id]; ok { existing.score += rrfScore existing.via = "hybrid" } else { - ins, err := db.GetInsightByID(vh.id) - if err != nil || ins == nil { + ins := cache.insights[vh.id] + if ins == nil { continue } anchorMap[vh.id] = &anchor{ - insight: ins, - score: rrfScore, - via: "vector", + score: rrfScore, + via: "vector", } } } } // Signal 3: Time-based ranking (MAGMA third RRF signal) - timeSorted := make([]*model.Insight, len(all)) - copy(timeSorted, all) - sort.Slice(timeSorted, func(i, j int) bool { - return timeSorted[i].CreatedAt.After(timeSorted[j].CreatedAt) - }) + timeSorted := all + byNewest := func(i, j int) bool { return timeSorted[i].CreatedAt.After(timeSorted[j].CreatedAt) } + // SQL already orders normal UTC timestamps. Verify absolute time order + // before reusing it: imported RFC3339 offsets need not sort lexically. + if !sort.SliceIsSorted(timeSorted, byNewest) { + timeSorted = append([]*model.Insight(nil), all...) + sort.Slice(timeSorted, byNewest) + } timeLimit := anchorTopK if timeLimit > len(timeSorted) { timeLimit = len(timeSorted) @@ -224,9 +214,8 @@ func IntentAwareRecall(db *store.DB, query string, queryVec []float64, } } else { anchorMap[ins.ID] = &anchor{ - insight: ins, - score: rrfScore, - via: "time", + score: rrfScore, + via: "time", } } } @@ -249,23 +238,20 @@ func IntentAwareRecall(db *store.DB, query string, queryVec []float64, // Initialize score map with anchors scoreMap := make(map[string]float64) viaMap := make(map[string]string) - insightMap := make(map[string]*model.Insight) for id, a := range anchorMap { scoreMap[id] = a.score viaMap[id] = a.via - insightMap[id] = a.insight } // Step 3: Beam search from each anchor for id, a := range anchorMap { - beamSearchFromAnchor(db, id, a.score, queryVec, weights, params, scoreMap, viaMap, insightMap, embedCache) + cache.beamSearchFromAnchor(id, a.score, weights, params, scoreMap, viaMap) } traversedCount := len(scoreMap) // Step 4: Multi-factor reranking - queryTokens := Tokenize(query) queryEntitySet := make(map[string]bool, len(queryEntities)) for _, e := range queryEntities { queryEntitySet[strings.ToLower(e)] = true @@ -287,7 +273,7 @@ func IntentAwareRecall(db *store.DB, query string, queryVec []float64, var graphMin, graphMax float64 first := true for id, graphRaw := range scoreMap { - ins, ok := insightMap[id] + ins, ok := cache.insights[id] if !ok { continue } @@ -317,20 +303,8 @@ func IntentAwareRecall(db *store.DB, query string, queryVec []float64, for i := range candidates { c := &candidates[i] - // keyword_score: token overlap (reuses pre-computed tokens from KeywordSearch) - if len(queryTokens) > 0 { - contentTokens := tokenCache[c.id] - if contentTokens == nil { - contentTokens = insightTokens(c.ins) - } - intersection := 0 - for t := range queryTokens { - if contentTokens[t] { - intersection++ - } - } - c.kwScore = float64(intersection) / float64(len(queryTokens)) - } + // keyword_score: exactly the overlap computed during anchor selection. + c.kwScore = keywordScores[c.id] // entity_score: entity overlap if len(queryEntitySet) > 0 { @@ -343,14 +317,9 @@ func IntentAwareRecall(db *store.DB, query string, queryVec []float64, c.entScore = float64(matched) / math.Max(1, float64(len(queryEntitySet))) } - // similarity: cosine similarity with query vector (uses pre-loaded cache) - if hasEmbeddings { - if nVec, ok := embedCache[c.id]; ok { - sim := embed.CosineSimilarity(queryVec, nVec) - if sim > 0 { - c.simScore = sim - } - } + // similarity: reuse the cosine computed during the embedding scan. + if sim := cache.similarities[c.id]; sim > 0 { + c.simScore = sim } // graph_score: min-max normalized beam search score @@ -505,20 +474,15 @@ func causalTopologicalSort(db *store.DB, results []RecallResult) []RecallResult return ordered } -// beamSearchFromAnchor performs beam search starting from a single anchor node. -// It uses a priority queue to keep the top beamWidth candidates at each depth level. -// embedCache provides pre-loaded embedding vectors (nil = no embeddings). -func beamSearchFromAnchor( - db *store.DB, +// beamSearchFromAnchor keeps traversal budgets and per-anchor visited sets local; +// adjacency and similarities are reused across anchors within this recall only. +func (cache *recallCache) beamSearchFromAnchor( startID string, startScore float64, - queryVec []float64, weights IntentWeights, params TraversalParams, scoreMap map[string]float64, viaMap map[string]string, - insightMap map[string]*model.Insight, - embedCache map[string][]float64, ) { visited := map[string]bool{startID: true} totalVisited := 1 @@ -545,7 +509,7 @@ func beamSearchFromAnchor( break } - edges, err := db.GetEdgesByNode(cur.id) + edges, err := cache.edgesFor(cur.id) if err != nil { continue } @@ -563,13 +527,8 @@ func beamSearchFromAnchor( // score_v = score_u + λ₁·φ(edgeType, intent) + λ₂·sim(v_neighbor, v_query) structural := weights[e.EdgeType] * e.Weight // φ(edgeType, intent) * edge_weight semantic := 0.0 - if queryVec != nil && embedCache != nil { - if nVec, ok := embedCache[neighborID]; ok { - cosSim := embed.CosineSimilarity(queryVec, nVec) - if cosSim > 0 { - semantic = cosSim - } - } + if sim := cache.similarities[neighborID]; sim > 0 { + semantic = sim } neighborScore := cur.score + lambda1*structural + lambda2*semantic @@ -577,12 +536,6 @@ func beamSearchFromAnchor( if existing, ok := scoreMap[neighborID]; !ok || neighborScore > existing { scoreMap[neighborID] = neighborScore viaMap[neighborID] = string(e.EdgeType) - if _, loaded := insightMap[neighborID]; !loaded { - ins, err := db.GetInsightByID(neighborID) - if err == nil && ins != nil { - insightMap[neighborID] = ins - } - } } if !visited[neighborID] { @@ -671,28 +624,16 @@ func (h *vectorHitMinHeap) Pop() interface{} { return item } -// vectorSearch performs brute-force cosine similarity search, loading embeddings from DB. -// Used by tests; the main recall path uses vectorSearchFromCache with a pre-loaded cache. +// vectorSearch is the database-backed entry used by the vector search tests. func vectorSearch(db *store.DB, queryVec []float64, limit int) []vectorHit { - dbEmbeds, err := db.GetAllEmbeddings() - if err != nil || len(dbEmbeds) == 0 { - return nil - } - cache := make(map[string][]float64, len(dbEmbeds)) - for _, e := range dbEmbeds { - if v := embed.DeserializeVector(e.Embedding); v != nil { - cache[e.ID] = v - } - } - return vectorSearchFromCache(cache, queryVec, limit) + return vectorSearchFromScores(loadQuerySimilarities(db, queryVec), limit) } -// vectorSearchFromCache performs cosine similarity search over pre-loaded embeddings. -// Uses a min-heap to maintain the top-k results in O(n log k) instead of O(n log n). -func vectorSearchFromCache(embedCache map[string][]float64, queryVec []float64, limit int) []vectorHit { +// vectorSearchFromScores selects exact top-k vector anchors in O(N log K), +// reusing similarities that beam search and reranking also consume. +func vectorSearchFromScores(similarities map[string]float64, limit int) []vectorHit { h := &vectorHitMinHeap{} - for id, vec := range embedCache { - sim := embed.CosineSimilarity(queryVec, vec) + for id, sim := range similarities { if sim <= 0.1 { continue } diff --git a/internal/memory/search/recall_cache.go b/internal/memory/search/recall_cache.go new file mode 100644 index 00000000..28731993 --- /dev/null +++ b/internal/memory/search/recall_cache.go @@ -0,0 +1,57 @@ +package search + +import ( + "github.com/mnemon-dev/mnemon/internal/memory/embed" + "github.com/mnemon-dev/mnemon/internal/memory/model" + "github.com/mnemon-dev/mnemon/internal/memory/store" +) + +// recallCache belongs to one synchronous recall. It is discarded afterwards so +// updates, deletions and changed query vectors cannot leave stale cached state. +type recallCache struct { + db *store.DB + insights map[string]*model.Insight + edges map[string][]*model.Edge + similarities map[string]float64 +} + +func newRecallCache(db *store.DB, all []*model.Insight, queryVec []float64) *recallCache { + c := &recallCache{ + db: db, insights: make(map[string]*model.Insight, len(all)), + edges: make(map[string][]*model.Edge), + } + for _, ins := range all { + c.insights[ins.ID] = ins + } + if queryVec != nil { + c.similarities = loadQuerySimilarities(db, queryVec) + } + return c +} + +func (c *recallCache) edgesFor(id string) ([]*model.Edge, error) { + if edges, ok := c.edges[id]; ok { + return edges, nil + } + edges, err := c.db.GetEdgesByNode(id) + if err == nil { + // Retain empty adjacency lists too, but let failed reads be retried. + c.edges[id] = edges + } + return edges, err +} + +func loadQuerySimilarities(db *store.DB, queryVec []float64) map[string]float64 { + scores := make(map[string]float64) + // The callback only computes a scalar; it never re-enters the single-conn DB. + err := db.ScanEmbeddings(func(id string, blob []byte) bool { + if vec := embed.DeserializeVector(blob); vec != nil { + scores[id] = embed.CosineSimilarity(queryVec, vec) + } + return true + }) + if err != nil { + return nil // preserve recall's keyword-only fallback on embedding failure + } + return scores +} diff --git a/internal/memory/search/recall_cache_test.go b/internal/memory/search/recall_cache_test.go new file mode 100644 index 00000000..2a0459b2 --- /dev/null +++ b/internal/memory/search/recall_cache_test.go @@ -0,0 +1,165 @@ +package search + +import ( + "fmt" + "math/rand" + "reflect" + "testing" + "time" + + "github.com/mnemon-dev/mnemon/internal/memory/embed" + "github.com/mnemon-dev/mnemon/internal/memory/model" +) + +func TestCachedBeamMatchesReference(t *testing.T) { + db := testDB(t) + now := time.Now().UTC() + rng := rand.New(rand.NewSource(23)) + vectors := make(map[string][]float64) + const n = 30 + for i := 0; i < n; i++ { + id := fmt.Sprintf("n-%02d", i) + insertInsight(t, db, id, id, "test", 3, nil, now) + vec := []float64{rng.Float64(), rng.Float64(), rng.Float64()} + blob := embed.SerializeVector(vec) + vectors[id] = embed.DeserializeVector(blob) + if err := db.UpdateEmbedding(id, blob); err != nil { + t.Fatal(err) + } + } + types := []model.EdgeType{model.EdgeTemporal, model.EdgeSemantic, model.EdgeCausal, model.EdgeEntity} + for range 120 { + e := &model.Edge{ + SourceID: fmt.Sprintf("n-%02d", rng.Intn(n)), TargetID: fmt.Sprintf("n-%02d", rng.Intn(n)), + EdgeType: types[rng.Intn(len(types))], Weight: rng.Float64(), CreatedAt: now, + } + if err := db.InsertEdge(e); err != nil { + t.Fatal(err) + } + } + // Keep legacy edges pointing at a soft-deleted node: traversal may still + // score it, but it must never be returned as an active recall candidate. + if _, err := db.Conn().Exec(`UPDATE insights SET deleted_at = ? WHERE id = 'n-29'`, now.Format(time.RFC3339)); err != nil { + t.Fatal(err) + } + delete(vectors, "n-29") + all, err := db.GetAllActiveInsights() + if err != nil { + t.Fatal(err) + } + for _, queryVec := range [][]float64{nil, {0.1, 0.5, 0.9}, {1, 0}} { + for _, intent := range []Intent{IntentGeneral, IntentWhy, IntentWhen, IntentEntity} { + for _, params := range []TraversalParams{{1, 1, 2}, {3, 4, 12}, {10, 5, 100}} { + cache := newRecallCache(db, all, queryVec) + gotScores, wantScores := map[string]float64{}, map[string]float64{} + gotVia, wantVia := map[string]string{}, map[string]string{} + wantInsights := map[string]*model.Insight{} + for _, anchor := range []string{"n-00", "n-01", "n-07", "n-00"} { + cache.beamSearchFromAnchor(anchor, 1, GetWeights(intent), params, gotScores, gotVia) + referenceBeamSearch(db, anchor, 1, queryVec, GetWeights(intent), params, wantScores, wantVia, wantInsights, vectors) + } + if !reflect.DeepEqual(gotScores, wantScores) || !reflect.DeepEqual(gotVia, wantVia) { + t.Fatalf("intent=%s params=%+v query=%v: cached scores/via differ from reference", intent, params, queryVec) + } + if cache.insights["n-29"] != nil { + t.Fatal("deleted candidate included") + } + } + } + } +} + +func TestRecallSignalsRefreshBetweenQueries(t *testing.T) { + db := testDB(t) + now := time.Now().UTC() + insertInsight(t, db, "one", "unrelated content", "test", 3, []string{"entity-only"}, now) + for _, tc := range []struct { + stored, query []float64 + want float64 + }{{[]float64{1, 0}, []float64{1, 0}, 1}, {[]float64{0, 1}, []float64{1, 0}, 0}, {[]float64{0, 1}, []float64{0, 1}, 1}} { + if err := db.UpdateEmbedding("one", embed.SerializeVector(tc.stored)); err != nil { + t.Fatal(err) + } + resp, err := IntentAwareRecall(db, "entity-only", tc.query, nil, 10, nil) + if err != nil || len(resp.Results) != 1 { + t.Fatalf("recall: %+v, %v", resp, err) + } + if r := resp.Results[0]; r.Signals.Similarity != tc.want || r.Signals.Keyword != 1 { + t.Fatalf("signals did not refresh: %+v", r.Signals) + } + } + if err := db.SoftDeleteInsight("one"); err != nil { + t.Fatal(err) + } + resp, err := IntentAwareRecall(db, "entity-only", []float64{0, 1}, nil, 10, nil) + if err != nil || len(resp.Results) != 0 { + t.Fatalf("deleted insight returned: %+v, %v", resp, err) + } +} + +func TestKeywordScoreCacheMatchesIndependentScoring(t *testing.T) { + insights := []*model.Insight{ + {ID: "content", Content: "查询 SQLite", Tags: []string{"性能"}, Entities: []string{"ProjectX"}}, + {ID: "boundaries", Content: "查", Tags: []string{"询"}, Entities: []string{"SQLite"}}, + {ID: "none", Content: "unrelated"}, + } + for _, query := range []string{"SQLite 查询 性能 ProjectX", "the and", "", "查询"} { + cache := map[string]float64{} + keywordSearchCached(insights, query, 1, cache) + q := Tokenize(query) + for _, ins := range insights { + // Independent union of individually tokenized fields: no cross-field + // CJK bigrams and no loss of tag/entity matches below the top-K cutoff. + union := Tokenize(ins.Content) + for _, field := range append(append([]string{}, ins.Tags...), ins.Entities...) { + for tok := range Tokenize(field) { + union[tok] = true + } + } + var matched float64 + for tok := range q { + if union[tok] { + matched++ + } + } + want := 0.0 + if len(q) > 0 { + want = matched / float64(len(q)) + } + if cache[ins.ID] != want { + t.Fatalf("query=%q id=%s: score=%v want=%v", query, ins.ID, cache[ins.ID], want) + } + } + } +} + +func TestRecallTimeAnchorsRespectOffsetsAndNewEdges(t *testing.T) { + db := testDB(t) + base := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC) + for i := 0; i <= anchorTopK; i++ { + created := base.Add(time.Duration(i) * time.Minute) + if i%2 == 1 { + created = created.In(time.FixedZone("+14", 14*60*60)) + } + id := fmt.Sprintf("time-%02d", i) + insertInsight(t, db, id, "time record", "test", 3, nil, created) + } + resp, err := IntentAwareRecall(db, "", nil, nil, 0, nil) + if err != nil || len(resp.Results) != anchorTopK || resp.Results[0].Insight.ID != "time-20" { + t.Fatalf("absolute-time anchors: %+v, %v", resp, err) + } + for _, r := range resp.Results { + if r.Insight.ID == "time-00" { + t.Fatal("oldest insight selected as a time anchor") + } + } + if err := db.InsertEdge(&model.Edge{ + SourceID: "time-20", TargetID: "time-00", EdgeType: model.EdgeCausal, Weight: 0.5, CreatedAt: base, + }); err != nil { + t.Fatal(err) + } + resp, err = IntentAwareRecall(db, "", nil, nil, 0, nil) + if err != nil || len(resp.Results) != anchorTopK+1 { + t.Fatalf("next recall failed to discover newly connected node: %+v, %v", resp, err) + } +} diff --git a/internal/memory/search/recall_reference_test.go b/internal/memory/search/recall_reference_test.go new file mode 100644 index 00000000..4d1827e8 --- /dev/null +++ b/internal/memory/search/recall_reference_test.go @@ -0,0 +1,109 @@ +package search + +import ( + "container/heap" + "github.com/mnemon-dev/mnemon/internal/memory/embed" + "github.com/mnemon-dev/mnemon/internal/memory/model" + "github.com/mnemon-dev/mnemon/internal/memory/store" +) + +// referenceBeamSearch is the traversal from ceebe145. Keep its independent +// database reads and cosine calculations as an oracle for cached traversal. +func referenceBeamSearch( + db *store.DB, + startID string, + startScore float64, + queryVec []float64, + weights IntentWeights, + params TraversalParams, + scoreMap map[string]float64, + viaMap map[string]string, + insightMap map[string]*model.Insight, + embedCache map[string][]float64, +) { + visited := map[string]bool{startID: true} + totalVisited := 1 + + // Seed the beam with the anchor + current := &beamHeap{{id: startID, score: startScore, depth: 0}} + heap.Init(current) + + for depth := 0; depth < params.MaxDepth; depth++ { + if current.Len() == 0 || totalVisited >= params.MaxVisited { + break + } + + // Collect all candidates for the next level + next := &beamHeap{} + heap.Init(next) + + // Process all nodes at the current level + for current.Len() > 0 && totalVisited < params.MaxVisited { + cur := heap.Pop(current).(beamItem) + if cur.depth != depth { + // Put it back — it's for a future level + heap.Push(current, cur) + break + } + + edges, err := db.GetEdgesByNode(cur.id) + if err != nil { + continue + } + + for _, e := range edges { + if totalVisited >= params.MaxVisited { + break + } + neighborID := e.TargetID + if neighborID == cur.id { + neighborID = e.SourceID + } + + // MAGMA transition score (P6): additive accumulation + // score_v = score_u + λ₁·φ(edgeType, intent) + λ₂·sim(v_neighbor, v_query) + structural := weights[e.EdgeType] * e.Weight // φ(edgeType, intent) * edge_weight + semantic := 0.0 + if queryVec != nil && embedCache != nil { + if nVec, ok := embedCache[neighborID]; ok { + cosSim := embed.CosineSimilarity(queryVec, nVec) + if cosSim > 0 { + semantic = cosSim + } + } + } + neighborScore := cur.score + lambda1*structural + lambda2*semantic + + // Update global score map if this path is better + if existing, ok := scoreMap[neighborID]; !ok || neighborScore > existing { + scoreMap[neighborID] = neighborScore + viaMap[neighborID] = string(e.EdgeType) + if _, loaded := insightMap[neighborID]; !loaded { + ins, err := db.GetInsightByID(neighborID) + if err == nil && ins != nil { + insightMap[neighborID] = ins + } + } + } + + if !visited[neighborID] { + visited[neighborID] = true + totalVisited++ + heap.Push(next, beamItem{ + id: neighborID, + score: neighborScore, + depth: depth + 1, + }) + } + } + } + + // Prune beam: keep only top beamWidth candidates for next level + pruned := &beamHeap{} + heap.Init(pruned) + for next.Len() > 0 && pruned.Len() < params.BeamWidth { + heap.Push(pruned, heap.Pop(next).(beamItem)) + } + current = pruned + } +} diff --git a/internal/memory/store/node.go b/internal/memory/store/node.go index bc4e1fff..5c373677 100644 --- a/internal/memory/store/node.go +++ b/internal/memory/store/node.go @@ -821,7 +821,7 @@ func (db *DB) ScanEmbeddings(fn func(id string, blob []byte) bool) error { } } } - return nil + return rows.Err() } // EmbeddingStats returns total insights and how many have embeddings. diff --git a/test/mnemond/architecture/mnemond_structure_test.go b/test/mnemond/architecture/mnemond_structure_test.go index 466f648c..7c6a5f9a 100644 --- a/test/mnemond/architecture/mnemond_structure_test.go +++ b/test/mnemond/architecture/mnemond_structure_test.go @@ -68,15 +68,16 @@ func assertNativeMemoryDoesNotImportAgency(t *testing.T, root string) { func assertMnemondPackageGraph(t *testing.T, root string) { t.Helper() want := map[string][]string{ - "internal/memory/embed": {}, - "internal/memory/model": {}, - "internal/memory/importdraft": {"internal/memory/model"}, - "internal/memory/store": {"internal/memory/embed", "internal/memory/model"}, + "internal/memory/embed": {}, + "internal/memory/internal/topk": {}, + "internal/memory/model": {}, + "internal/memory/importdraft": {"internal/memory/model"}, + "internal/memory/store": {"internal/memory/embed", "internal/memory/model"}, "internal/memory/search": { - "internal/memory/embed", "internal/memory/model", "internal/memory/store", + "internal/memory/embed", "internal/memory/internal/topk", "internal/memory/model", "internal/memory/store", }, "internal/memory/graph": { - "internal/memory/embed", "internal/memory/model", "internal/memory/search", + "internal/memory/embed", "internal/memory/internal/topk", "internal/memory/model", "internal/memory/search", "internal/memory/store", }, "internal/memory/setup/assets": {}, From 766c3965292676776e47c00e56afc44d9d52097d Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 19:00:15 +0800 Subject: [PATCH 5/8] refactor(memory): reuse insert statements within transactions Prepare insight and edge insert statements lazily inside their owning transaction, so import batches and graph writes do not compile identical SQL for every row. Commit and rollback close the statements; callback panics now roll back and release the connection before transaction-local pointers are cleared. Validated commit, rollback, replacement, subsequent transactions, panic cleanup, make test, Memory race tests, all 258 CLI E2E assertions, and insert scaling benchmarks. --- internal/memory/store/db.go | 36 +++++++- internal/memory/store/edge.go | 3 +- .../memory/store/insert_transaction_test.go | 86 +++++++++++++++++++ internal/memory/store/node.go | 3 +- 4 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 internal/memory/store/insert_transaction_test.go diff --git a/internal/memory/store/db.go b/internal/memory/store/db.go index bd2d33aa..530068b2 100644 --- a/internal/memory/store/db.go +++ b/internal/memory/store/db.go @@ -31,12 +31,17 @@ type dbExecer interface { QueryRow(string, ...any) *sql.Row } -// DB wraps the SQLite database connection. +// DB wraps the SQLite database connection. Store operations must not run +// concurrently with InTransaction on the same handle. type DB struct { conn *sql.DB tx *sql.Tx // current active transaction (nil = no transaction) path string readOnly bool + // Lazily prepared by the active transaction, which closes them on commit + // or rollback. InTransaction clears both pointers before another call. + txInsertInsight *sql.Stmt + txInsertEdge *sql.Stmt } // IsReadOnly returns true if the database was opened in read-only mode. @@ -50,6 +55,25 @@ func (db *DB) execer() dbExecer { return db.conn } +// execInsert reuses compilation for repeated inserts in one transaction. The +// caller still owns the SQL, arguments and domain validation. Outside a +// transaction, there is no statement cache or extra connection to manage. +func (db *DB) execInsert(prepared **sql.Stmt, query string, args ...any) error { + if db.tx == nil { + _, err := db.conn.Exec(query, args...) + return err + } + if *prepared == nil { + stmt, err := db.tx.Prepare(query) + if err != nil { + return err + } + *prepared = stmt + } + _, err := (*prepared).Exec(args...) + return err +} + // InTransaction runs fn inside a single SQL transaction. // All store methods called within fn will use the transaction automatically. func (db *DB) InTransaction(fn func() error) error { @@ -61,9 +85,15 @@ func (db *DB) InTransaction(fn func() error) error { return fmt.Errorf("begin tx: %w", err) } db.tx = tx - defer func() { db.tx = nil }() + defer func() { + // Also release the connection and prepared statements if fn panics. + // After a successful Commit this is a harmless ErrTxDone. + _ = tx.Rollback() + db.tx = nil + db.txInsertInsight = nil + db.txInsertEdge = nil + }() if err := fn(); err != nil { - tx.Rollback() return err } return tx.Commit() diff --git a/internal/memory/store/edge.go b/internal/memory/store/edge.go index 81a1a50c..e12203c9 100644 --- a/internal/memory/store/edge.go +++ b/internal/memory/store/edge.go @@ -13,13 +13,12 @@ func (db *DB) InsertEdge(e *model.Edge) error { if e.EdgeType == model.EdgeSupersedes && e.SourceID == e.TargetID { return fmt.Errorf("supersedes requires distinct insights") } - _, err := db.execer().Exec( + return db.execInsert(&db.txInsertEdge, `INSERT OR REPLACE INTO edges (source_id, target_id, edge_type, weight, metadata, created_at) VALUES (?, ?, ?, ?, ?, ?)`, e.SourceID, e.TargetID, string(e.EdgeType), e.Weight, e.MetadataJSON(), e.CreatedAt.Format(time.RFC3339), ) - return err } // GetEdgesByNode returns all edges where the given node is source or target. diff --git a/internal/memory/store/insert_transaction_test.go b/internal/memory/store/insert_transaction_test.go new file mode 100644 index 00000000..bcf22116 --- /dev/null +++ b/internal/memory/store/insert_transaction_test.go @@ -0,0 +1,86 @@ +package store + +import ( + "database/sql" + "errors" + "testing" + "time" + + "github.com/mnemon-dev/mnemon/internal/memory/model" +) + +func TestInsertStatementsFollowTransactionOutcome(t *testing.T) { + db := testDB(t) + abort := errors.New("abort batch") + for _, rollback := range []bool{true, false} { + err := db.InTransaction(func() error { + for _, id := range []string{"a", "b"} { + if err := db.InsertInsight(makeInsight(id, id, 3)); err != nil { + return err + } + } + for _, weight := range []float64{0.5, 0.9} { + if err := db.InsertEdge(&model.Edge{ + SourceID: "a", TargetID: "b", EdgeType: model.EdgeSemantic, + Weight: weight, CreatedAt: time.Now().UTC(), + }); err != nil { + return err + } + } + if rollback { + return abort + } + return nil + }) + if rollback { + if !errors.Is(err, abort) { + t.Fatalf("rollback: %v", err) + } + if _, err := db.GetInsightByID("a"); !errors.Is(err, sql.ErrNoRows) { + t.Fatalf("rolled-back insert persisted: %v", err) + } + } else if err != nil { + t.Fatal(err) + } + edges, err := db.GetAllEdges() + if err != nil { + t.Fatal(err) + } + if rollback && len(edges) != 0 || !rollback && (len(edges) != 1 || edges[0].Weight != 0.9) { + t.Fatalf("rollback=%v: unexpected edges %+v", rollback, edges) + } + } + // A committed statement must not leak into the next transaction either. + if err := db.InTransaction(func() error { return db.InsertInsight(makeInsight("c", "next transaction", 3)) }); err != nil { + t.Fatal(err) + } + if err := db.InsertInsight(makeInsight("d", "outside transaction", 3)); err != nil { + t.Fatal(err) + } +} + +func TestInsertTransactionPanicReleasesConnection(t *testing.T) { + db := testDB(t) + func() { + defer func() { + if value := recover(); value != "abort" { + t.Fatalf("unexpected panic: %v", value) + } + }() + _ = db.InTransaction(func() error { + if err := db.InsertInsight(makeInsight("panic", "rolled back", 3)); err != nil { + t.Fatal(err) + } + panic("abort") + }) + }() + if inUse := db.Conn().Stats().InUse; inUse != 0 { + t.Fatalf("transaction kept %d connections after panic", inUse) + } + if _, err := db.GetInsightByID("panic"); !errors.Is(err, sql.ErrNoRows) { + t.Fatalf("panic insert persisted: %v", err) + } + if err := db.InTransaction(func() error { return db.InsertInsight(makeInsight("panic", "retry", 3)) }); err != nil { + t.Fatal(err) + } +} diff --git a/internal/memory/store/node.go b/internal/memory/store/node.go index 5c373677..db702302 100644 --- a/internal/memory/store/node.go +++ b/internal/memory/store/node.go @@ -107,7 +107,7 @@ func parseAutoPruneMinAge(raw string) (time.Duration, error) { // InsertInsight inserts a new insight into the database. func (db *DB) InsertInsight(i *model.Insight) error { - _, err := db.execer().Exec( + return db.execInsert(&db.txInsertInsight, `INSERT INTO insights (id, content, category, importance, tags, entities, source, access_count, stored_at, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, i.ID, i.Content, string(i.Category), i.Importance, @@ -115,7 +115,6 @@ func (db *DB) InsertInsight(i *model.Insight) error { time.Now().UTC().Format(time.RFC3339), i.CreatedAt.Format(time.RFC3339), i.UpdatedAt.Format(time.RFC3339), ) - return err } // GetInsightByID returns a single insight by ID (excludes soft-deleted). From b599b3c24d6c0a11ced75e24b632f047f0f74e2f Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 19:09:15 +0800 Subject: [PATCH 6/8] docs(memory): report algorithm complexity and measured tradeoffs Document the read, recall, graph and storage complexity audit in English and Chinese, with N=1/10/100/1000/10000 comparisons, dense graph results, operation-count bounds and reproducible benchmark commands. Include all 1080 final samples with wall time, process CPU and allocation metrics, including unchanged controls and small-workload regressions. Record successful product build, deterministic CI, Memory race tests and 258 CLI E2E assertions, and distinguish the remaining exact-scan and durability costs from the optimized paths. --- .../benchmarks/2026-10-03-memory-after.txt | 574 ++++++++++++++++++ .../benchmarks/2026-10-03-memory-before.txt | 574 ++++++++++++++++++ .../memory-algorithm-performance.md | 278 +++++++++ .../memory-algorithm-performance.md | 94 +++ 4 files changed, 1520 insertions(+) create mode 100644 docs/development/benchmarks/2026-10-03-memory-after.txt create mode 100644 docs/development/benchmarks/2026-10-03-memory-before.txt create mode 100644 docs/development/memory-algorithm-performance.md create mode 100644 docs/zh/development/memory-algorithm-performance.md diff --git a/docs/development/benchmarks/2026-10-03-memory-after.txt b/docs/development/benchmarks/2026-10-03-memory-after.txt new file mode 100644 index 00000000..20e3360c --- /dev/null +++ b/docs/development/benchmarks/2026-10-03-memory-after.txt @@ -0,0 +1,574 @@ +# Date: 2026-10-03 (Asia/Shanghai) +# Production revision: 766c3965292676776e47c00e56afc44d9d52097d +# Benchmark sources: a21d783b (identical in both binaries) +# Five alternating-order rounds; -test.run=^$ -test.bench=BenchmarkMemory -test.benchmem -test.benchtime=100ms -test.count=1 -test.cpu=1 +# round=1 loadavg=(4.98681640625, 11.32470703125, 17.83544921875) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10523 ns/op 10468 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 8706 12599 ns/op 12440 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5358 21986 ns/op 21862 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8788 14191 ns/op 14182 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5337 22631 ns/op 22632 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 6772 16094 ns/op 16091 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7402 15932 ns/op 15943 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5479 21947 ns/op 21911 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18798 6476 ns/op 6454 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 35282 3818 ns/op 3733 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 18358 7339 ns/op 6797 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1539 73856 ns/op 72574 cpu-ns/op 7281 B/op 176 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1591 80042 ns/op 79920 cpu-ns/op 10193 B/op 203 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2949 43943 ns/op 43889 cpu-ns/op 10048 B/op 197 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9336 15526 ns/op 14142 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 8557 13742 ns/op 13621 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7911 17069 ns/op 16499 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 13984 ns/op 12009 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 2770 37670 ns/op 35955 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3223 47109 ns/op 45513 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7341 20891 ns/op 18865 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 4986 25408 ns/op 24379 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4669 23882 ns/op 23806 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 6086 19523 ns/op 19520 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4947 24356 ns/op 24359 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 9987 14299 ns/op 14205 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4477 29670 ns/op 29545 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1911 63012 ns/op 62821 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 460 264455 ns/op 263980 cpu-ns/op 81608 B/op 2108 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 422 282628 ns/op 282055 cpu-ns/op 105641 B/op 2241 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 328 361024 ns/op 359695 cpu-ns/op 126933 B/op 2784 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2415 66220 ns/op 63711 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2154 51648 ns/op 51221 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2168 57571 ns/op 57526 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10084 ns/op 10066 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 570 209230 ns/op 208333 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3387 39912 ns/op 39824 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8666 14323 ns/op 14311 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3106 41808 ns/op 41707 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 4206 26058 ns/op 26037 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1935 64383 ns/op 63506 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 1980 55596 ns/op 55443 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1300 88794 ns/op 87808 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 417 291891 ns/op 290580 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 332 370489 ns/op 368864 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 58 2062549 ns/op 2059086 cpu-ns/op 722851 B/op 17893 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 61 2376409 ns/op 2343852 cpu-ns/op 975078 B/op 19535 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 54 2362382 ns/op 2357000 cpu-ns/op 1015048 B/op 20501 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1969 63927 ns/op 63643 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 291 406904 ns/op 405770 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2145 58246 ns/op 58236 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10365 ns/op 10346 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 66 1980197 ns/op 1976076 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3302 39551 ns/op 39498 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8694 14325 ns/op 14313 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3184 59391 ns/op 49161 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 4742 24058 ns/op 23977 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 249 470435 ns/op 469663 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 320 371505 ns/op 371503 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 147 806382 ns/op 800844 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2770712 ns/op 2763423 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 48 3049199 ns/op 3043000 cpu-ns/op 2181206 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6461625 ns/op 6451062 cpu-ns/op 4001403 B/op 90803 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 12 9499490 ns/op 9473500 cpu-ns/op 6718598 B/op 110743 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 12 10179913 ns/op 10155583 cpu-ns/op 6837472 B/op 114190 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 872 144471 ns/op 144475 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 36 3951735 ns/op 3940556 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2107 58789 ns/op 58755 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10602 ns/op 10567 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 5 23381042 ns/op 23180000 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3008 41131 ns/op 40980 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8322 14781 ns/op 14665 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3003 42654 ns/op 42481 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4960 23574 ns/op 23569 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 18 6510317 ns/op 6496778 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 9441496 ns/op 9438583 cpu-ns/op 1323 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 14434649 ns/op 14421429 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 26726990 ns/op 26717000 cpu-ns/op 20161140 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 29017323 ns/op 29003250 cpu-ns/op 21405500 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 3 57448583 ns/op 55075667 cpu-ns/op 36679834 B/op 819872 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 85448458 ns/op 81548000 cpu-ns/op 59497620 B/op 922007 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 78307416 ns/op 77500000 cpu-ns/op 59612872 B/op 925726 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 121 962324 ns/op 962669 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 40563264 ns/op 40492667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2074 58284 ns/op 58311 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1147 96804 ns/op 75046 cpu-ns/op 1830 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 619 410585 ns/op 230570 cpu-ns/op 11912 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 96 1409761 ns/op 1333573 cpu-ns/op 113440 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 35275778 ns/op 34432000 cpu-ns/op 1129509 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 476778583 ns/op 452539000 cpu-ns/op 11282088 B/op 280033 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 13692 8765 ns/op 8634 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1574 75518 ns/op 60093 cpu-ns/op 3351 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1453 85494 ns/op 85490 cpu-ns/op 6493 B/op 152 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7628 15581 ns/op 15573 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 692 163113 ns/op 148718 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 381 329541 ns/op 306593 cpu-ns/op 20868 B/op 515 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1725 69231 ns/op 69217 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 104 1149965 ns/op 1104231 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 174 712055 ns/op 674385 cpu-ns/op 51166 B/op 1367 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 205 582705 ns/op 582971 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 8 12693375 ns/op 11908125 cpu-ns/op 1904830 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 140 842722 ns/op 809257 cpu-ns/op 52665 B/op 1415 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 11890032 ns/op 11794111 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 223278375 ns/op 202709000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 54 2134391 ns/op 2042444 cpu-ns/op 52675 B/op 1415 allocs/op +BenchmarkMemoryDenseRecall/N=1 2120 57993 ns/op 57974 cpu-ns/op 10000 B/op 195 allocs/op +BenchmarkMemoryDenseRecall/N=10 232 507483 ns/op 506147 cpu-ns/op 242576 B/op 6673 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 19499514 ns/op 19467833 cpu-ns/op 10289032 B/op 340504 allocs/op +PASS +# round=2 loadavg=(5.06396484375, 10.93017578125, 17.54150390625) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10108 ns/op 10096 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11005 ns/op 10995 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5852 21104 ns/op 21089 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8760 14282 ns/op 14271 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5468 22880 ns/op 22821 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7009 16161 ns/op 16159 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7515 15482 ns/op 15481 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5527 21615 ns/op 21606 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18727 6375 ns/op 6367 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 35066 3411 ns/op 3399 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19341 6191 ns/op 6172 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1795 67850 ns/op 67825 cpu-ns/op 7280 B/op 176 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1670 75667 ns/op 75619 cpu-ns/op 10193 B/op 203 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 3046 42066 ns/op 41982 cpu-ns/op 10048 B/op 197 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9658 13128 ns/op 13111 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9693 13074 ns/op 13057 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 8162 14697 ns/op 14685 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10108 ns/op 10097 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4686 30800 ns/op 30656 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3328 39811 ns/op 39723 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 8838 14344 ns/op 14331 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5414 22876 ns/op 22860 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5038 22908 ns/op 22902 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5731 20173 ns/op 20183 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4887 24344 ns/op 24335 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14273 ns/op 14191 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4281 30480 ns/op 30364 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1891 64526 ns/op 64353 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 448 274682 ns/op 272074 cpu-ns/op 81607 B/op 2108 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 420 288141 ns/op 287529 cpu-ns/op 105640 B/op 2241 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 346 342297 ns/op 341598 cpu-ns/op 126933 B/op 2784 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2467 52631 ns/op 52569 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2398 50645 ns/op 50544 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2188 61326 ns/op 60918 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10201 11542 ns/op 11322 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 518 253459 ns/op 240994 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3274 41739 ns/op 41521 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8614 14492 ns/op 14475 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3080 42620 ns/op 42537 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 4255 26222 ns/op 26139 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1940 62996 ns/op 62800 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2202 56168 ns/op 56124 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1261 93692 ns/op 92615 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 416 291266 ns/op 290204 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 312 383116 ns/op 378837 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 58 2196922 ns/op 2148069 cpu-ns/op 722852 B/op 17893 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 60 2232720 ns/op 2226500 cpu-ns/op 975077 B/op 19535 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 57 2345601 ns/op 2341561 cpu-ns/op 1015049 B/op 20501 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2031 63353 ns/op 63228 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 276 430157 ns/op 428460 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2064 59265 ns/op 59235 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 11110 ns/op 10912 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 68 1979745 ns/op 1973809 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3240 40232 ns/op 40170 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8455 14916 ns/op 14904 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3212 41534 ns/op 41466 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 5038 23260 ns/op 23254 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 253 493782 ns/op 489300 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 271 423718 ns/op 407823 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 141 838102 ns/op 826908 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 50 2940386 ns/op 2906240 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 44 3053973 ns/op 3045409 cpu-ns/op 2181209 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6423427 ns/op 6408938 cpu-ns/op 4001412 B/op 90803 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 12 9268688 ns/op 9249667 cpu-ns/op 6715426 B/op 110742 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 10 10212904 ns/op 10200000 cpu-ns/op 6837422 B/op 114190 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 867 148666 ns/op 147300 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 34 3948263 ns/op 3932735 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2126 60093 ns/op 59875 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10118 ns/op 10109 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 5 21390817 ns/op 21287000 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3156 40279 ns/op 40258 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8401 14689 ns/op 14687 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3050 42040 ns/op 41956 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4988 23253 ns/op 23263 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 18 10932734 ns/op 7722833 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 10 10530758 ns/op 10216100 cpu-ns/op 1336 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 15504976 ns/op 15208857 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 27246302 ns/op 27179500 cpu-ns/op 20161144 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 29373260 ns/op 29363500 cpu-ns/op 21405496 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 50150270 ns/op 50113000 cpu-ns/op 36685700 B/op 819872 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 71246167 ns/op 70775000 cpu-ns/op 59487228 B/op 921737 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 74271666 ns/op 73328000 cpu-ns/op 59593480 B/op 925058 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 120 962961 ns/op 963292 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 41230472 ns/op 41223000 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2095 58320 ns/op 58304 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1051 96560 ns/op 76714 cpu-ns/op 1814 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 613 193540 ns/op 174873 cpu-ns/op 11912 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 100 1230794 ns/op 1203650 cpu-ns/op 113438 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 42096583 ns/op 36914333 cpu-ns/op 1129504 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 463858208 ns/op 459203000 cpu-ns/op 11281976 B/op 280032 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14250 8396 ns/op 8394 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1554 76401 ns/op 59692 cpu-ns/op 3322 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1454 89250 ns/op 88915 cpu-ns/op 6554 B/op 153 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7765 15928 ns/op 15920 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 648 169436 ns/op 154136 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 388 317665 ns/op 300662 cpu-ns/op 20875 B/op 515 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1765 68647 ns/op 68561 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 96 1153125 ns/op 1113469 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 163 695351 ns/op 647012 cpu-ns/op 51187 B/op 1368 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 206 576596 ns/op 576830 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12031917 ns/op 11813333 cpu-ns/op 1904827 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 139 848974 ns/op 816223 cpu-ns/op 52658 B/op 1414 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 7 15449958 ns/op 13130714 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 205866167 ns/op 193075000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 56 2049642 ns/op 1970411 cpu-ns/op 52644 B/op 1413 allocs/op +BenchmarkMemoryDenseRecall/N=1 2121 57823 ns/op 57795 cpu-ns/op 10000 B/op 195 allocs/op +BenchmarkMemoryDenseRecall/N=10 234 514469 ns/op 513538 cpu-ns/op 242575 B/op 6673 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 19489062 ns/op 19429333 cpu-ns/op 10289034 B/op 340504 allocs/op +PASS +# round=3 loadavg=(4.9033203125, 10.0068359375, 16.82275390625) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10869 ns/op 10747 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11227 ns/op 11132 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5752 20972 ns/op 20958 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8982 14149 ns/op 13994 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5468 22426 ns/op 22344 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7431 16402 ns/op 16359 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 6580 15815 ns/op 15787 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5156 21354 ns/op 21338 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18936 6367 ns/op 6355 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 35062 3388 ns/op 3375 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19992 6070 ns/op 6035 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1822 67597 ns/op 67564 cpu-ns/op 7280 B/op 176 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1664 74955 ns/op 74892 cpu-ns/op 10193 B/op 203 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 3100 41411 ns/op 41364 cpu-ns/op 10048 B/op 197 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 8845 13036 ns/op 13030 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 13098 ns/op 13085 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 8112 14837 ns/op 14782 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10031 ns/op 10023 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4813 31045 ns/op 30616 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3351 40625 ns/op 40490 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 8767 14218 ns/op 14206 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5517 22399 ns/op 22384 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5274 23075 ns/op 23065 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 6055 20581 ns/op 20300 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4971 25843 ns/op 25071 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 6213 17820 ns/op 16714 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3765 33252 ns/op 32310 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1689 66803 ns/op 66179 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 457 262397 ns/op 261928 cpu-ns/op 81608 B/op 2108 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 423 283561 ns/op 282920 cpu-ns/op 105641 B/op 2241 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 342 340919 ns/op 339599 cpu-ns/op 126933 B/op 2784 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2509 53070 ns/op 52960 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2295 50657 ns/op 50530 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2179 57761 ns/op 57704 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10633 ns/op 10512 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 544 226508 ns/op 223347 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3171 42030 ns/op 41779 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8713 14231 ns/op 14216 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3196 41428 ns/op 41350 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 4483 26293 ns/op 26273 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1939 62464 ns/op 62446 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2186 55329 ns/op 55287 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1306 88783 ns/op 87966 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 430 286436 ns/op 285256 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 230 451216 ns/op 407665 cpu-ns/op 222681 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 57 2100536 ns/op 2095561 cpu-ns/op 722853 B/op 17893 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 61 2416020 ns/op 2378115 cpu-ns/op 975078 B/op 19535 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 57 2492490 ns/op 2437684 cpu-ns/op 1015048 B/op 20501 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2000 63085 ns/op 62958 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 290 414273 ns/op 412959 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2131 58911 ns/op 58849 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10628 11294 ns/op 11109 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 67 2258900 ns/op 2187746 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3216 41225 ns/op 40982 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8484 14522 ns/op 14503 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3151 41786 ns/op 41730 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 5118 23452 ns/op 23316 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 253 466999 ns/op 467095 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 319 370361 ns/op 370464 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 146 815310 ns/op 809623 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2822265 ns/op 2814346 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 50 2961903 ns/op 2954160 cpu-ns/op 2181207 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6419120 ns/op 6403062 cpu-ns/op 4001403 B/op 90803 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 13 9430308 ns/op 9410846 cpu-ns/op 6715177 B/op 110742 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 10 10542988 ns/op 10437400 cpu-ns/op 6837424 B/op 114190 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 870 143798 ns/op 143800 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 36 3902417 ns/op 3895139 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2132 57994 ns/op 57967 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10176 ns/op 10177 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 5 23526233 ns/op 22672200 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3171 39651 ns/op 39593 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8331 14198 ns/op 14205 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3115 41535 ns/op 41512 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4633 23674 ns/op 23678 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 18 6288898 ns/op 6292056 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 10154396 ns/op 9796167 cpu-ns/op 1323 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 14694530 ns/op 14705429 cpu-ns/op 16547806 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 27295229 ns/op 27280500 cpu-ns/op 20161140 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 28626271 ns/op 28607000 cpu-ns/op 21405492 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 53782500 ns/op 53769000 cpu-ns/op 36667484 B/op 819871 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 79364062 ns/op 76180500 cpu-ns/op 59497620 B/op 922007 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 75689729 ns/op 75466500 cpu-ns/op 59612872 B/op 925726 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 123 950083 ns/op 950650 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 41598083 ns/op 41598667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2109 58254 ns/op 58265 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1114 91079 ns/op 73068 cpu-ns/op 1792 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 625 183875 ns/op 166262 cpu-ns/op 11913 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 99 1198988 ns/op 1172980 cpu-ns/op 113438 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 35104986 ns/op 35000667 cpu-ns/op 1129504 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 465766750 ns/op 458416000 cpu-ns/op 11282088 B/op 280033 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14162 8441 ns/op 8435 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1600 74511 ns/op 59021 cpu-ns/op 3360 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1423 85840 ns/op 85835 cpu-ns/op 6518 B/op 152 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7711 15595 ns/op 15514 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 656 166020 ns/op 149620 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 396 331906 ns/op 301942 cpu-ns/op 20870 B/op 515 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1732 70480 ns/op 70033 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 91 1123352 ns/op 1090505 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 180 662654 ns/op 637828 cpu-ns/op 51179 B/op 1367 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 204 580075 ns/op 580588 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12147880 ns/op 11698333 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 139 849109 ns/op 814669 cpu-ns/op 52677 B/op 1415 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 11726500 ns/op 11644778 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 178348166 ns/op 175201000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 55 2108231 ns/op 2029400 cpu-ns/op 52662 B/op 1413 allocs/op +BenchmarkMemoryDenseRecall/N=1 2154 58051 ns/op 58011 cpu-ns/op 10000 B/op 195 allocs/op +BenchmarkMemoryDenseRecall/N=10 237 499911 ns/op 498346 cpu-ns/op 242574 B/op 6673 allocs/op +BenchmarkMemoryDenseRecall/N=100 4 25274636 ns/op 23844500 cpu-ns/op 10292288 B/op 340506 allocs/op +PASS +# round=4 loadavg=(5.2919921875, 9.84228515625, 16.64453125) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10576 11042 ns/op 10908 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 12251 ns/op 12040 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5768 20995 ns/op 20982 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8746 14116 ns/op 14111 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5481 22365 ns/op 22346 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7142 15862 ns/op 15852 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7750 16585 ns/op 16301 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5502 21401 ns/op 21397 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18114 6593 ns/op 6570 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 34280 3485 ns/op 3474 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19346 6199 ns/op 6167 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1814 67314 ns/op 67236 cpu-ns/op 7281 B/op 176 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1668 75203 ns/op 75126 cpu-ns/op 10193 B/op 203 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 3142 41632 ns/op 41576 cpu-ns/op 10048 B/op 197 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9662 13157 ns/op 13134 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9828 13113 ns/op 13100 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7908 14603 ns/op 14594 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10010 ns/op 9997 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4706 30080 ns/op 29916 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3327 39723 ns/op 39628 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 8539 14664 ns/op 14524 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5164 22936 ns/op 22850 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5143 23015 ns/op 23014 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 6028 19813 ns/op 19814 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4873 24464 ns/op 24450 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14245 ns/op 14153 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4562 29862 ns/op 29738 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1861 64239 ns/op 64050 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 442 266855 ns/op 266364 cpu-ns/op 81607 B/op 2108 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 428 285863 ns/op 283530 cpu-ns/op 105640 B/op 2241 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 100 1012125 ns/op 413470 cpu-ns/op 126934 B/op 2784 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 1869 58144 ns/op 57335 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2373 52267 ns/op 52025 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2163 57695 ns/op 57703 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10194 ns/op 10192 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 574 209969 ns/op 209054 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3322 39878 ns/op 39808 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8593 14489 ns/op 14404 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3170 41596 ns/op 41508 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 4372 26464 ns/op 26461 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1897 62357 ns/op 62372 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2229 54433 ns/op 54439 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1320 88899 ns/op 88059 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 423 283417 ns/op 282364 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 328 362878 ns/op 361613 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 55 2106416 ns/op 2094364 cpu-ns/op 722855 B/op 17893 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 61 2211078 ns/op 2206082 cpu-ns/op 975076 B/op 19535 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 58 2332216 ns/op 2306448 cpu-ns/op 1015048 B/op 20501 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2082 62375 ns/op 62325 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 296 404064 ns/op 402831 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2194 58244 ns/op 58191 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10472 ns/op 10466 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 63 2022781 ns/op 1997667 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3363 39412 ns/op 39358 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8616 14294 ns/op 14285 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3175 41364 ns/op 41304 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 5184 22963 ns/op 22960 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 256 465522 ns/op 465633 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 320 372576 ns/op 372309 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 150 791825 ns/op 786607 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2775006 ns/op 2765962 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 49 3042761 ns/op 3032898 cpu-ns/op 2181208 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6600469 ns/op 6588562 cpu-ns/op 4001403 B/op 90803 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 12 9629142 ns/op 9609083 cpu-ns/op 6715426 B/op 110742 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 12 10150698 ns/op 10123750 cpu-ns/op 6837473 B/op 114190 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 858 144165 ns/op 144117 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 34 3878244 ns/op 3870353 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2155 58049 ns/op 58027 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 12045 9926 ns/op 9927 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 6 21349535 ns/op 21281167 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3188 40018 ns/op 40012 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8356 14440 ns/op 14442 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3003 41865 ns/op 41728 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4914 23211 ns/op 23208 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 18 6776312 ns/op 6613778 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 10 10569738 ns/op 10396900 cpu-ns/op 1336 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 14868869 ns/op 14856714 cpu-ns/op 16547809 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 26759698 ns/op 26756750 cpu-ns/op 20161140 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 28635396 ns/op 28612250 cpu-ns/op 21405500 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 3 50553111 ns/op 50529333 cpu-ns/op 36679621 B/op 819871 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 73756104 ns/op 73693500 cpu-ns/op 59497620 B/op 922007 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 76413938 ns/op 74941500 cpu-ns/op 59612872 B/op 925726 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 122 961403 ns/op 961557 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 40958889 ns/op 40949667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2095 59294 ns/op 59285 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1119 91732 ns/op 74262 cpu-ns/op 1815 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 630 186425 ns/op 171689 cpu-ns/op 11912 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 98 1214986 ns/op 1185786 cpu-ns/op 113438 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 36000681 ns/op 35761000 cpu-ns/op 1129509 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 457471042 ns/op 456321000 cpu-ns/op 11282104 B/op 280034 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14518 8232 ns/op 8229 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1603 73464 ns/op 57875 cpu-ns/op 3285 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1450 85634 ns/op 85638 cpu-ns/op 6546 B/op 152 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7664 15593 ns/op 15600 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 700 161665 ns/op 147981 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 387 314739 ns/op 295488 cpu-ns/op 20883 B/op 516 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1760 69269 ns/op 69274 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 97 1132518 ns/op 1101412 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 188 635054 ns/op 611856 cpu-ns/op 51163 B/op 1366 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 206 578900 ns/op 578869 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12018120 ns/op 11798333 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 139 846847 ns/op 814036 cpu-ns/op 52644 B/op 1413 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 11557875 ns/op 11561778 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 192177000 ns/op 185037000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 57 2135355 ns/op 2048439 cpu-ns/op 52674 B/op 1415 allocs/op +BenchmarkMemoryDenseRecall/N=1 2169 58186 ns/op 58082 cpu-ns/op 10000 B/op 195 allocs/op +BenchmarkMemoryDenseRecall/N=10 234 504756 ns/op 503842 cpu-ns/op 242575 B/op 6673 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 18916764 ns/op 18885333 cpu-ns/op 10289134 B/op 340505 allocs/op +PASS +# round=5 loadavg=(6.06982421875, 9.341796875, 16.0693359375) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10281 ns/op 10213 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11372 ns/op 11267 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5871 21247 ns/op 21125 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8632 14519 ns/op 14500 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5440 23007 ns/op 22996 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7258 16402 ns/op 16360 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7210 15969 ns/op 15895 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5319 21695 ns/op 21687 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18753 6346 ns/op 6336 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 34603 3438 ns/op 3426 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19224 6437 ns/op 6301 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1542 71393 ns/op 71020 cpu-ns/op 7280 B/op 176 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1657 76594 ns/op 76535 cpu-ns/op 10193 B/op 203 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2991 53742 ns/op 48341 cpu-ns/op 10048 B/op 197 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9559 13877 ns/op 13818 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9678 13827 ns/op 13731 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7996 15247 ns/op 15177 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10210 ns/op 10206 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4639 31073 ns/op 30963 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3336 40985 ns/op 40789 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7483 15680 ns/op 15479 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5269 22949 ns/op 22937 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5058 23314 ns/op 23303 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 6074 19880 ns/op 19884 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4995 24299 ns/op 24285 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14540 ns/op 14445 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4495 30602 ns/op 30485 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1824 64596 ns/op 64428 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 444 270492 ns/op 270014 cpu-ns/op 81608 B/op 2108 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 405 293038 ns/op 292526 cpu-ns/op 105641 B/op 2241 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 350 345348 ns/op 344506 cpu-ns/op 126933 B/op 2784 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2427 52831 ns/op 52769 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2386 51189 ns/op 51034 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2173 58327 ns/op 58272 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10002 ns/op 9991 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 566 210903 ns/op 210140 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3306 40168 ns/op 40078 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8535 14326 ns/op 14313 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3261 41722 ns/op 41626 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 4464 26228 ns/op 26091 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1906 62566 ns/op 62472 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2186 54438 ns/op 54468 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1300 91133 ns/op 90307 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 412 293576 ns/op 292478 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 325 369884 ns/op 368455 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 58 2093950 ns/op 2089793 cpu-ns/op 722856 B/op 17893 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 58 2258732 ns/op 2253776 cpu-ns/op 975078 B/op 19535 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 58 2367983 ns/op 2361621 cpu-ns/op 1015048 B/op 20501 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2035 63307 ns/op 63255 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 291 408794 ns/op 407838 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2175 58850 ns/op 58804 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10290 ns/op 10292 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 64 1958005 ns/op 1952844 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3376 39373 ns/op 39315 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8448 14594 ns/op 14571 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3066 42689 ns/op 42583 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 5049 24293 ns/op 23773 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 256 467539 ns/op 467664 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 320 371977 ns/op 372066 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 147 809736 ns/op 805374 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2930123 ns/op 2895750 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 49 3112382 ns/op 3077898 cpu-ns/op 2181209 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6457576 ns/op 6443062 cpu-ns/op 4001403 B/op 90803 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 12 9455875 ns/op 9435250 cpu-ns/op 6715506 B/op 110743 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 12 10520996 ns/op 10497500 cpu-ns/op 6837473 B/op 114190 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 859 144748 ns/op 144729 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 36 3970899 ns/op 3963472 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2132 58417 ns/op 58379 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10068 ns/op 10070 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 5 21328350 ns/op 21092000 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3123 39497 ns/op 39472 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8434 14627 ns/op 14626 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3012 42339 ns/op 42317 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 5029 24238 ns/op 24027 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 18 7742917 ns/op 7433278 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 9435496 ns/op 9436167 cpu-ns/op 1323 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 16085250 ns/op 15625143 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 27731677 ns/op 27412500 cpu-ns/op 20161144 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 28965250 ns/op 28939000 cpu-ns/op 21405500 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 53908229 ns/op 53771000 cpu-ns/op 36685700 B/op 819872 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 73208854 ns/op 73096500 cpu-ns/op 59497604 B/op 922006 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 78675230 ns/op 78049500 cpu-ns/op 59612872 B/op 925726 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 121 961104 ns/op 961306 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 42998597 ns/op 42975667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2095 58718 ns/op 58710 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1107 92790 ns/op 75821 cpu-ns/op 1783 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 598 189566 ns/op 171308 cpu-ns/op 11944 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 92 1244848 ns/op 1219163 cpu-ns/op 113439 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 37876125 ns/op 36816667 cpu-ns/op 1129509 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 468183126 ns/op 462097000 cpu-ns/op 11282104 B/op 280034 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14385 8342 ns/op 8345 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1604 74899 ns/op 58932 cpu-ns/op 3303 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1448 87011 ns/op 87048 cpu-ns/op 6543 B/op 153 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7782 15699 ns/op 15696 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 664 171472 ns/op 153464 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 392 315009 ns/op 294469 cpu-ns/op 20883 B/op 516 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1743 93390 ns/op 77441 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 87 1302106 ns/op 1207310 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 181 649413 ns/op 619315 cpu-ns/op 51154 B/op 1366 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 206 580958 ns/op 581126 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 13408245 ns/op 12254222 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 141 845313 ns/op 808773 cpu-ns/op 52674 B/op 1415 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 11455111 ns/op 11460778 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 182439583 ns/op 177120000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 55 2094973 ns/op 1973764 cpu-ns/op 52673 B/op 1414 allocs/op +BenchmarkMemoryDenseRecall/N=1 2156 61256 ns/op 60225 cpu-ns/op 10000 B/op 195 allocs/op +BenchmarkMemoryDenseRecall/N=10 234 510954 ns/op 509385 cpu-ns/op 242576 B/op 6673 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 18929188 ns/op 18898167 cpu-ns/op 10295432 B/op 340506 allocs/op +PASS diff --git a/docs/development/benchmarks/2026-10-03-memory-before.txt b/docs/development/benchmarks/2026-10-03-memory-before.txt new file mode 100644 index 00000000..175ab248 --- /dev/null +++ b/docs/development/benchmarks/2026-10-03-memory-before.txt @@ -0,0 +1,574 @@ +# Date: 2026-10-03 (Asia/Shanghai) +# Production revision: 4d312c4ebb42bf9f85442120fad4b9e85d4779e2 +# Benchmark sources: a21d783b (identical in both binaries) +# Five alternating-order rounds; -test.run=^$ -test.bench=BenchmarkMemory -test.benchmem -test.benchtime=100ms -test.count=1 -test.cpu=1 +# round=1 loadavg=(5.09423828125, 11.6689453125, 18.0703125) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 11974 10044 ns/op 9976 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11128 ns/op 11078 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5425 24071 ns/op 23460 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7246 16618 ns/op 16372 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5275 23896 ns/op 23585 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 5868 17165 ns/op 17056 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7100 16168 ns/op 16170 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5090 22816 ns/op 22791 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19050 6171 ns/op 6056 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 28298 4269 ns/op 4230 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16326 7339 ns/op 7285 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1670 70353 ns/op 70040 cpu-ns/op 8696 B/op 194 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1600 79029 ns/op 78838 cpu-ns/op 11745 B/op 224 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 3022 43383 ns/op 43328 cpu-ns/op 11584 B/op 218 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11355 ns/op 11342 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11245 ns/op 11229 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7228 17003 ns/op 16956 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10762 ns/op 10591 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4220 33139 ns/op 32966 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3012 44308 ns/op 44218 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7777 15829 ns/op 15803 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5366 23225 ns/op 23189 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4813 25306 ns/op 25303 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5865 21072 ns/op 20801 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4518 25748 ns/op 25711 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14421 ns/op 14276 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3235 38044 ns/op 37826 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1714 74157 ns/op 73866 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 138 868483 ns/op 867442 cpu-ns/op 193701 B/op 5560 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 132 908489 ns/op 907182 cpu-ns/op 222371 B/op 5727 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 100 1102378 ns/op 1100880 cpu-ns/op 267932 B/op 7096 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2502 51985 ns/op 51910 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1740 95562 ns/op 84469 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2484 51025 ns/op 50473 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10256 ns/op 10246 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 451 265997 ns/op 263517 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2464 52388 ns/op 52101 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5264 23657 ns/op 23623 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2778 48281 ns/op 48194 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1188 100567 ns/op 100566 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1789 67628 ns/op 67469 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 1977 59390 ns/op 59329 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1302 88181 ns/op 87363 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 336 354446 ns/op 352682 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 270 439763 ns/op 437744 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 26 4846423 ns/op 4839154 cpu-ns/op 1322968 B/op 34130 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 20 6147815 ns/op 6144700 cpu-ns/op 1792616 B/op 42059 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 16 7594010 ns/op 7561688 cpu-ns/op 2021360 B/op 49497 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1896 70527 ns/op 70411 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 174 683869 ns/op 680569 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 337 354560 ns/op 353098 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10277 ns/op 10273 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 51 2562225 ns/op 2521235 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 997 123017 ns/op 123034 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1714 69409 ns/op 69394 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1293 97621 ns/op 97565 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 126 943004 ns/op 942548 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 238 500071 ns/op 499370 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 319 373127 ns/op 373248 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 150 805457 ns/op 800133 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 34 3567094 ns/op 3523941 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 32 3737694 ns/op 3722406 cpu-ns/op 3631357 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 10 10569421 ns/op 10548200 cpu-ns/op 5824949 B/op 115138 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 7 15888214 ns/op 15859286 cpu-ns/op 9325374 B/op 150411 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 6 18379993 ns/op 18320667 cpu-ns/op 9669925 B/op 161570 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 562 224530 ns/op 223847 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 15 6727233 ns/op 6686800 cpu-ns/op 4315145 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 43 3373743 ns/op 3362209 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10867 10914 ns/op 10757 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 3 45415361 ns/op 40430667 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 50 2317298 ns/op 2293840 cpu-ns/op 16295 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 96 1213356 ns/op 1206448 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 93 1297581 ns/op 1262075 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 6 17439160 ns/op 17433167 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 10 10708912 ns/op 10710300 cpu-ns/op 569 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 9353573 ns/op 9287417 cpu-ns/op 1304 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 14447798 ns/op 14444143 cpu-ns/op 16547802 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 33631386 ns/op 33609250 cpu-ns/op 34241400 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 35639819 ns/op 35604000 cpu-ns/op 36019717 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 78694084 ns/op 78128500 cpu-ns/op 50873340 B/op 925188 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 1 102096333 ns/op 101097000 cpu-ns/op 79348088 B/op 1070432 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 102887708 ns/op 101032000 cpu-ns/op 79722576 B/op 1082013 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 64 1895579 ns/op 1891672 cpu-ns/op 989249 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 76679625 ns/op 74854000 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 44800417 ns/op 43783667 cpu-ns/op 23987317 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1102 91673 ns/op 73997 cpu-ns/op 1747 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 398 282898 ns/op 267274 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 52 2316889 ns/op 2287500 cpu-ns/op 133186 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 47549861 ns/op 45767667 cpu-ns/op 1329210 B/op 30018 allocs/op +BenchmarkMemoryInsert/N=10000 1 526996042 ns/op 517955000 cpu-ns/op 13281736 B/op 300028 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14845 8039 ns/op 8028 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1614 72584 ns/op 58002 cpu-ns/op 3310 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1257 97039 ns/op 96843 cpu-ns/op 7561 B/op 175 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7827 15179 ns/op 15145 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 680 163188 ns/op 147221 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 298 452266 ns/op 408654 cpu-ns/op 24058 B/op 591 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1730 70047 ns/op 69235 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 96 1107993 ns/op 1079833 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 122 980634 ns/op 957861 cpu-ns/op 58141 B/op 1476 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 205 586303 ns/op 586512 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 11834815 ns/op 11607667 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 33 3393795 ns/op 3353333 cpu-ns/op 73701 B/op 1526 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 8 12559406 ns/op 11686000 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 177462083 ns/op 174473000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 2 65546730 ns/op 61646000 cpu-ns/op 297900 B/op 1535 allocs/op +BenchmarkMemoryDenseRecall/N=1 2154 59525 ns/op 59408 cpu-ns/op 11424 B/op 211 allocs/op +BenchmarkMemoryDenseRecall/N=10 38 3500414 ns/op 3493605 cpu-ns/op 1482479 B/op 52179 allocs/op +BenchmarkMemoryDenseRecall/N=100 1 126572292 ns/op 126394000 cpu-ns/op 68485280 B/op 2521029 allocs/op +PASS +# round=2 loadavg=(5.33837890625, 10.7041015625, 17.34521484375) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10087 ns/op 10075 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11372 ns/op 11273 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5431 22498 ns/op 22480 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7872 15640 ns/op 15631 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5308 23314 ns/op 23243 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 5952 17018 ns/op 16986 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7436 16517 ns/op 16491 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5257 22891 ns/op 22865 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19321 6110 ns/op 6101 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 28216 4246 ns/op 4220 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16418 7337 ns/op 7256 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1770 71392 ns/op 70944 cpu-ns/op 8697 B/op 194 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1598 77827 ns/op 77738 cpu-ns/op 11745 B/op 224 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2887 43756 ns/op 43667 cpu-ns/op 11584 B/op 218 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11542 ns/op 11525 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11371 ns/op 11348 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7318 17001 ns/op 16984 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10130 ns/op 10120 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4129 33031 ns/op 32775 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2943 44231 ns/op 44132 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7867 15754 ns/op 15718 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5253 24793 ns/op 24548 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4784 25399 ns/op 25385 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5680 20761 ns/op 20718 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4708 25595 ns/op 25566 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14347 ns/op 14197 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3043 38498 ns/op 38211 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1678 75276 ns/op 74973 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 135 878647 ns/op 877267 cpu-ns/op 193700 B/op 5560 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 130 921755 ns/op 919508 cpu-ns/op 222371 B/op 5727 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 100 1124124 ns/op 1121630 cpu-ns/op 267932 B/op 7096 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2389 54193 ns/op 54080 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1714 71879 ns/op 71621 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2539 48581 ns/op 48452 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10204 ns/op 10186 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 464 256379 ns/op 255183 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2512 52262 ns/op 52121 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5216 23781 ns/op 23750 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2718 48704 ns/op 48597 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1180 101193 ns/op 101005 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1820 69645 ns/op 68085 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 1988 58805 ns/op 58851 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1298 89677 ns/op 88818 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 331 357688 ns/op 355798 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 270 444339 ns/op 442130 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 25 4863272 ns/op 4852440 cpu-ns/op 1322976 B/op 34130 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 20 6179177 ns/op 6167200 cpu-ns/op 1792606 B/op 42059 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 16 7525763 ns/op 7488562 cpu-ns/op 2021347 B/op 49497 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1879 70772 ns/op 70626 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 178 671998 ns/op 669281 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 330 371945 ns/op 368276 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 11089 ns/op 10844 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 51 2414618 ns/op 2408078 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 998 123605 ns/op 123522 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1746 69718 ns/op 69592 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1278 97929 ns/op 97733 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 126 951014 ns/op 947889 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 241 501239 ns/op 499066 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 320 375058 ns/op 374928 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 147 803057 ns/op 797238 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 38 3772700 ns/op 3703921 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 27 6011398 ns/op 4790630 cpu-ns/op 3631572 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 10 10835812 ns/op 10813300 cpu-ns/op 5824936 B/op 115138 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 7 15636512 ns/op 15608857 cpu-ns/op 9320076 B/op 150410 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 6 17818340 ns/op 17781500 cpu-ns/op 9669936 B/op 161570 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 566 221380 ns/op 221002 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 16 6588409 ns/op 6516000 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 40 3340693 ns/op 3333550 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10747 ns/op 10615 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 3 36693333 ns/op 35507000 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 50 2241150 ns/op 2221220 cpu-ns/op 16295 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 86 1194671 ns/op 1193465 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 91 1168310 ns/op 1168538 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 6 19165021 ns/op 18699167 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 10 11306504 ns/op 10766700 cpu-ns/op 569 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 10170528 ns/op 9588083 cpu-ns/op 1304 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 15185875 ns/op 14824000 cpu-ns/op 16547806 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 33445990 ns/op 33421750 cpu-ns/op 34241396 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 35267111 ns/op 35249000 cpu-ns/op 36007370 B/op 420471 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 77042604 ns/op 76330500 cpu-ns/op 50873340 B/op 925188 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 1 117930959 ns/op 110939000 cpu-ns/op 79320560 B/op 1069748 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 1 107525000 ns/op 105775000 cpu-ns/op 79722544 B/op 1082013 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 48 2263919 ns/op 2199875 cpu-ns/op 989249 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 83344875 ns/op 78011500 cpu-ns/op 43615536 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2 54389542 ns/op 47356500 cpu-ns/op 23987320 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1129 91247 ns/op 73568 cpu-ns/op 1763 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 414 290931 ns/op 266053 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 54 2269640 ns/op 2246000 cpu-ns/op 133186 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 42380069 ns/op 42133333 cpu-ns/op 1329253 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 558817167 ns/op 550995000 cpu-ns/op 13281968 B/op 300030 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14811 8097 ns/op 8085 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1611 73257 ns/op 58906 cpu-ns/op 3287 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1248 96836 ns/op 96643 cpu-ns/op 7571 B/op 175 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7686 15646 ns/op 15565 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 668 167488 ns/op 151922 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 297 408890 ns/op 387071 cpu-ns/op 24026 B/op 589 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1722 101953 ns/op 78280 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 81 1244023 ns/op 1167457 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 100 1031392 ns/op 1004360 cpu-ns/op 58123 B/op 1475 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 205 580088 ns/op 580185 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 11904301 ns/op 11674889 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 33 3851927 ns/op 3611939 cpu-ns/op 73718 B/op 1527 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 11808657 ns/op 11751333 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 193059834 ns/op 185735000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 2 55850250 ns/op 55801000 cpu-ns/op 297844 B/op 1534 allocs/op +BenchmarkMemoryDenseRecall/N=1 2007 60544 ns/op 60354 cpu-ns/op 11424 B/op 211 allocs/op +BenchmarkMemoryDenseRecall/N=10 37 3519738 ns/op 3515027 cpu-ns/op 1482480 B/op 52179 allocs/op +BenchmarkMemoryDenseRecall/N=100 1 128008125 ns/op 127746000 cpu-ns/op 68485296 B/op 2521029 allocs/op +PASS +# round=3 loadavg=(5.0751953125, 10.30029296875, 17.04541015625) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10452 ns/op 10414 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11350 ns/op 11340 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5388 22741 ns/op 22721 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7834 15961 ns/op 15939 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5367 23817 ns/op 23802 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7033 16698 ns/op 16699 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7548 16058 ns/op 16058 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5264 23603 ns/op 23373 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19888 6041 ns/op 6027 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 27697 4291 ns/op 4269 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16554 7316 ns/op 7281 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1753 69742 ns/op 69697 cpu-ns/op 8696 B/op 194 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1640 77189 ns/op 77142 cpu-ns/op 11745 B/op 224 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2940 44486 ns/op 44407 cpu-ns/op 11584 B/op 218 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11656 ns/op 11646 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11509 ns/op 11500 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7288 17001 ns/op 16976 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10254 ns/op 10242 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4070 33409 ns/op 33310 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3018 44598 ns/op 44464 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7712 15870 ns/op 15859 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5247 23637 ns/op 23631 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4785 26066 ns/op 25866 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5876 21344 ns/op 21018 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4716 25582 ns/op 25566 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 9942 14188 ns/op 14091 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3253 37444 ns/op 37242 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1688 74979 ns/op 74657 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 135 885194 ns/op 884807 cpu-ns/op 193702 B/op 5560 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 127 939208 ns/op 935882 cpu-ns/op 222371 B/op 5727 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 100 1122866 ns/op 1121370 cpu-ns/op 267933 B/op 7096 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2476 53026 ns/op 52983 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1761 71448 ns/op 71176 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2505 48397 ns/op 48260 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10174 ns/op 10164 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 454 260597 ns/op 259449 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2406 53184 ns/op 52916 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5053 24135 ns/op 24004 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2766 48777 ns/op 48656 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1184 101381 ns/op 100868 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1779 66965 ns/op 66943 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2012 58849 ns/op 58829 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1298 88251 ns/op 87387 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 330 361270 ns/op 359227 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 274 435969 ns/op 433949 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 25 4826565 ns/op 4821160 cpu-ns/op 1322966 B/op 34130 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 21 6100052 ns/op 6095238 cpu-ns/op 1792596 B/op 42059 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 16 7605867 ns/op 7572000 cpu-ns/op 2021356 B/op 49497 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1806 72395 ns/op 71921 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 175 676889 ns/op 674103 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 338 355992 ns/op 354734 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10168 ns/op 10167 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 54 2477894 ns/op 2449222 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 1011 123423 ns/op 123371 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1726 71235 ns/op 70477 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1272 97077 ns/op 97026 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 124 957993 ns/op 949161 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 242 510261 ns/op 503070 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 312 380889 ns/op 380317 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 127 915861 ns/op 895220 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 36 3539041 ns/op 3516972 cpu-ns/op 3425395 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 31 3806497 ns/op 3791935 cpu-ns/op 3631396 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 10 10305088 ns/op 10288200 cpu-ns/op 5824914 B/op 115137 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 7 15546815 ns/op 15516000 cpu-ns/op 9320077 B/op 150410 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 6 17529611 ns/op 17480667 cpu-ns/op 9669941 B/op 161570 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 570 219749 ns/op 219554 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 16 6491763 ns/op 6477125 cpu-ns/op 4315145 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 42 3351809 ns/op 3342500 cpu-ns/op 2417217 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10283 ns/op 10281 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 3 37331319 ns/op 36535667 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 49 2682088 ns/op 2587429 cpu-ns/op 16295 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 68 1589423 ns/op 1462353 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 87 1712735 ns/op 1522471 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 5 23965400 ns/op 21596400 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 9 17480005 ns/op 14051667 cpu-ns/op 569 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 15730142 ns/op 12313167 cpu-ns/op 1304 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 3 36768958 ns/op 25166667 cpu-ns/op 16547810 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 41070722 ns/op 38435333 cpu-ns/op 34241400 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 42275847 ns/op 39871333 cpu-ns/op 36019722 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 1 122901167 ns/op 100291000 cpu-ns/op 50855136 B/op 925188 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 1 358480125 ns/op 152551000 cpu-ns/op 79348104 B/op 1070434 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 1 137217791 ns/op 122634000 cpu-ns/op 79695864 B/op 1081199 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 37 2891464 ns/op 2697162 cpu-ns/op 989249 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 76310730 ns/op 75178500 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 43796764 ns/op 43308333 cpu-ns/op 23987312 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1146 91398 ns/op 74791 cpu-ns/op 1759 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 415 283229 ns/op 267682 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 51 2251647 ns/op 2222725 cpu-ns/op 133184 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 41928597 ns/op 41688000 cpu-ns/op 1329248 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 667094542 ns/op 575536000 cpu-ns/op 13281984 B/op 300031 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 15139 7894 ns/op 7890 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1651 71733 ns/op 58219 cpu-ns/op 3302 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1294 97950 ns/op 97903 cpu-ns/op 7502 B/op 174 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7969 15395 ns/op 15384 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 655 166165 ns/op 150455 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 295 410045 ns/op 388332 cpu-ns/op 24048 B/op 590 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1749 70391 ns/op 69897 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 85 1276567 ns/op 1165965 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 110 1049003 ns/op 1019609 cpu-ns/op 58122 B/op 1475 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 202 584972 ns/op 584183 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12271333 ns/op 11877111 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 32 3412411 ns/op 3369312 cpu-ns/op 73675 B/op 1524 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 12993778 ns/op 12563778 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 190026459 ns/op 175693000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 2 57084438 ns/op 56044000 cpu-ns/op 297908 B/op 1535 allocs/op +BenchmarkMemoryDenseRecall/N=1 2107 59004 ns/op 58966 cpu-ns/op 11424 B/op 211 allocs/op +BenchmarkMemoryDenseRecall/N=10 37 3500063 ns/op 3494784 cpu-ns/op 1482480 B/op 52179 allocs/op +BenchmarkMemoryDenseRecall/N=100 1 129983292 ns/op 127674000 cpu-ns/op 68485312 B/op 2521029 allocs/op +PASS +# round=4 loadavg=(5.4111328125, 9.5888671875, 16.39599609375) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10592 ns/op 10478 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11235 ns/op 11222 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5524 22323 ns/op 22183 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8024 15666 ns/op 15654 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5334 23024 ns/op 23013 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7154 16744 ns/op 16646 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7524 16140 ns/op 16135 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5301 22932 ns/op 22890 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 20402 5916 ns/op 5906 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 27908 4237 ns/op 4215 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16143 7551 ns/op 7421 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1738 70957 ns/op 70946 cpu-ns/op 8696 B/op 194 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1610 78267 ns/op 78174 cpu-ns/op 11745 B/op 224 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 3052 43338 ns/op 43294 cpu-ns/op 11584 B/op 218 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11562 ns/op 11480 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 12382 ns/op 11781 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7362 16777 ns/op 16763 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10298 ns/op 10267 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4185 32878 ns/op 32789 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2948 47324 ns/op 46626 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7556 17344 ns/op 16875 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5290 24217 ns/op 24086 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4680 25443 ns/op 25439 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5982 19853 ns/op 19856 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4771 26558 ns/op 26266 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 16332 ns/op 15641 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3034 44607 ns/op 41952 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1711 76518 ns/op 75874 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 136 870139 ns/op 864794 cpu-ns/op 193700 B/op 5560 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 130 918901 ns/op 917623 cpu-ns/op 222371 B/op 5727 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 100 1145868 ns/op 1137270 cpu-ns/op 267932 B/op 7096 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2517 55211 ns/op 54831 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1698 78508 ns/op 76899 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2265 49733 ns/op 49427 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10384 ns/op 10372 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 460 257655 ns/op 256833 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2518 53594 ns/op 52934 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 4090 24789 ns/op 24202 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2662 49420 ns/op 48532 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1179 100540 ns/op 100567 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1785 67319 ns/op 67131 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2083 59497 ns/op 59212 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1285 88469 ns/op 87681 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 333 355962 ns/op 354126 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 267 442956 ns/op 440891 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 26 4781136 ns/op 4771885 cpu-ns/op 1322973 B/op 34130 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 20 6147662 ns/op 6135100 cpu-ns/op 1792614 B/op 42059 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 16 7586901 ns/op 7528688 cpu-ns/op 2021354 B/op 49497 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1918 68519 ns/op 68446 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 168 701317 ns/op 676560 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 334 364291 ns/op 359323 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10156 ns/op 10158 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 54 2439605 ns/op 2432407 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 1005 123354 ns/op 123291 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1720 69774 ns/op 69776 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1278 97150 ns/op 97106 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 127 937503 ns/op 936732 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 238 500137 ns/op 498882 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 320 374023 ns/op 374106 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 150 794685 ns/op 789420 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 37 3459470 ns/op 3447324 cpu-ns/op 3425395 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 32 4753701 ns/op 4369844 cpu-ns/op 3631360 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 10 10518767 ns/op 10486500 cpu-ns/op 5824956 B/op 115138 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 7 15784101 ns/op 15744429 cpu-ns/op 9325514 B/op 150411 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 6 17540188 ns/op 17508833 cpu-ns/op 9669930 B/op 161570 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 561 218548 ns/op 218196 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 16 6512943 ns/op 6499250 cpu-ns/op 4315145 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 38 3379913 ns/op 3366711 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 12052 9913 ns/op 9914 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 3 34691722 ns/op 34236000 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 57 2049784 ns/op 2048579 cpu-ns/op 16294 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 90 1114877 ns/op 1110422 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 90 1167224 ns/op 1168389 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 6 18552285 ns/op 18364667 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 10 10708138 ns/op 10693400 cpu-ns/op 569 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 9410590 ns/op 9416917 cpu-ns/op 1304 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 15129488 ns/op 14800857 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 33425740 ns/op 33400250 cpu-ns/op 34241396 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 35991944 ns/op 35969000 cpu-ns/op 36019717 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 77402416 ns/op 76686500 cpu-ns/op 50873340 B/op 925188 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 1 102736083 ns/op 100887000 cpu-ns/op 79320592 B/op 1069748 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 1 109955334 ns/op 108947000 cpu-ns/op 79722560 B/op 1082013 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 64 1819381 ns/op 1815828 cpu-ns/op 989249 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 75939750 ns/op 75361500 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 46443347 ns/op 45634000 cpu-ns/op 23987322 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1112 101009 ns/op 80175 cpu-ns/op 1725 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 408 287583 ns/op 266382 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 52 2278417 ns/op 2257308 cpu-ns/op 133186 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 42826805 ns/op 42484667 cpu-ns/op 1329216 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 586417250 ns/op 555831000 cpu-ns/op 13281832 B/op 300028 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14452 8285 ns/op 8224 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1561 75286 ns/op 60086 cpu-ns/op 3389 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1236 100248 ns/op 99739 cpu-ns/op 7463 B/op 174 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7432 15537 ns/op 15526 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 667 171800 ns/op 154030 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 262 431863 ns/op 399366 cpu-ns/op 24038 B/op 590 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1725 69567 ns/op 69299 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 100 1262421 ns/op 1134570 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 87 1355789 ns/op 1155736 cpu-ns/op 58120 B/op 1475 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 177 640307 ns/op 619644 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 8 14969677 ns/op 12724000 cpu-ns/op 1904826 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 32 3510749 ns/op 3385031 cpu-ns/op 73739 B/op 1528 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 15550107 ns/op 13809333 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 190350208 ns/op 184412000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 2 70270000 ns/op 64529000 cpu-ns/op 297852 B/op 1535 allocs/op +BenchmarkMemoryDenseRecall/N=1 2152 58819 ns/op 58777 cpu-ns/op 11424 B/op 211 allocs/op +BenchmarkMemoryDenseRecall/N=10 37 3554420 ns/op 3549000 cpu-ns/op 1482477 B/op 52179 allocs/op +BenchmarkMemoryDenseRecall/N=100 1 126099250 ns/op 125855000 cpu-ns/op 68485392 B/op 2521029 allocs/op +PASS +# round=5 loadavg=(5.71923828125, 9.4462890625, 16.2255859375) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10247 ns/op 10206 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11191 ns/op 11179 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5487 23314 ns/op 23102 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7956 16004 ns/op 15938 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5359 23023 ns/op 23017 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 6955 16337 ns/op 16336 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7574 16016 ns/op 16018 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5083 22352 ns/op 22346 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19902 5997 ns/op 5987 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 28069 4267 ns/op 4240 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 12757 8940 ns/op 7885 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1740 75719 ns/op 74056 cpu-ns/op 8697 B/op 194 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1604 78729 ns/op 78643 cpu-ns/op 11745 B/op 224 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2935 44255 ns/op 44176 cpu-ns/op 11584 B/op 218 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11843 ns/op 11805 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11745 ns/op 11724 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7093 17432 ns/op 17334 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10214 ns/op 10204 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4190 33064 ns/op 32936 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2965 44806 ns/op 44703 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7809 15817 ns/op 15797 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5210 23388 ns/op 23379 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4810 24942 ns/op 24936 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5886 40122 ns/op 27760 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4808 25032 ns/op 25030 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14527 ns/op 14286 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3237 36863 ns/op 36650 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1711 73648 ns/op 73231 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 129 919575 ns/op 918341 cpu-ns/op 193700 B/op 5560 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 129 923814 ns/op 922209 cpu-ns/op 222371 B/op 5727 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 100 1117049 ns/op 1115620 cpu-ns/op 267932 B/op 7096 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2473 53509 ns/op 53467 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1242 90960 ns/op 83903 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2424 51768 ns/op 51058 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10568 ns/op 10535 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 372 300015 ns/op 270546 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2424 74413 ns/op 59407 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 4561 29831 ns/op 25830 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2472 60120 ns/op 52837 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 997 116580 ns/op 105796 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1321 84870 ns/op 75687 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 1987 66236 ns/op 62116 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1065 106318 ns/op 104241 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 302 452593 ns/op 428119 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 126 796603 ns/op 703341 cpu-ns/op 375775 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 24 5086616 ns/op 5068792 cpu-ns/op 1322964 B/op 34130 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 19 6775934 ns/op 6623211 cpu-ns/op 1792612 B/op 42059 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 15 7967817 ns/op 7889133 cpu-ns/op 2021365 B/op 49497 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1828 74870 ns/op 74389 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 148 770508 ns/op 722372 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 308 395130 ns/op 389682 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10830 ns/op 10775 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 50 3023448 ns/op 2727000 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 902 140366 ns/op 136457 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1650 73272 ns/op 72593 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1081 103549 ns/op 103009 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 92 1437737 ns/op 1113207 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 208 808694 ns/op 607837 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 230 458632 ns/op 437583 cpu-ns/op 1259 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 100 1326135 ns/op 1136230 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 34 3726346 ns/op 3682735 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 30 4157031 ns/op 4106500 cpu-ns/op 3631435 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 10 11528375 ns/op 11448200 cpu-ns/op 5824928 B/op 115138 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 7 18333506 ns/op 17708143 cpu-ns/op 9320092 B/op 150410 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 5 21406133 ns/op 20842000 cpu-ns/op 9669833 B/op 161570 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 483 238127 ns/op 237108 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 16 7112888 ns/op 6990375 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 37 4018360 ns/op 3759459 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 8989 12663 ns/op 12087 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 3 39917319 ns/op 37588667 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 51 2707221 ns/op 2625078 cpu-ns/op 16295 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 100 1156236 ns/op 1155500 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 92 1164807 ns/op 1164696 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 6 17592847 ns/op 17606167 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 10 10659146 ns/op 10645500 cpu-ns/op 569 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 12 9232361 ns/op 9226917 cpu-ns/op 1304 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 7 14643875 ns/op 14589857 cpu-ns/op 16547802 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 43812264 ns/op 38396333 cpu-ns/op 34241400 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 36254653 ns/op 35977667 cpu-ns/op 36007365 B/op 420471 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 77568542 ns/op 76940000 cpu-ns/op 50873332 B/op 925188 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 1 100331416 ns/op 99804000 cpu-ns/op 79348104 B/op 1070432 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 1 136139917 ns/op 127903000 cpu-ns/op 79722576 B/op 1082013 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 67 1809072 ns/op 1808522 cpu-ns/op 989248 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 81623354 ns/op 80084000 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2 56387438 ns/op 53418500 cpu-ns/op 23987320 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1076 95312 ns/op 77213 cpu-ns/op 1731 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 381 282366 ns/op 265614 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 52 2228205 ns/op 2204481 cpu-ns/op 133186 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 42194459 ns/op 41986667 cpu-ns/op 1329253 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 539028208 ns/op 533818000 cpu-ns/op 13281968 B/op 300030 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 15356 7842 ns/op 7837 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1623 73437 ns/op 57850 cpu-ns/op 3376 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1285 96984 ns/op 96975 cpu-ns/op 7459 B/op 174 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7660 15250 ns/op 15249 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 658 167455 ns/op 152476 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 297 404983 ns/op 384929 cpu-ns/op 24054 B/op 591 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1737 69035 ns/op 68911 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 96 1109843 ns/op 1080833 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 122 986016 ns/op 962631 cpu-ns/op 58140 B/op 1476 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 204 583976 ns/op 584162 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 11903861 ns/op 11663889 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 33 3346658 ns/op 3314909 cpu-ns/op 73696 B/op 1526 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 9 11695829 ns/op 11674000 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 195078708 ns/op 185466000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 2 55312167 ns/op 55329500 cpu-ns/op 297924 B/op 1536 allocs/op +BenchmarkMemoryDenseRecall/N=1 2140 58959 ns/op 58964 cpu-ns/op 11424 B/op 211 allocs/op +BenchmarkMemoryDenseRecall/N=10 37 3551816 ns/op 3537919 cpu-ns/op 1482476 B/op 52179 allocs/op +BenchmarkMemoryDenseRecall/N=100 1 125359084 ns/op 125057000 cpu-ns/op 68485360 B/op 2521029 allocs/op +PASS diff --git a/docs/development/memory-algorithm-performance.md b/docs/development/memory-algorithm-performance.md new file mode 100644 index 00000000..fdf81dee --- /dev/null +++ b/docs/development/memory-algorithm-performance.md @@ -0,0 +1,278 @@ +# Memory algorithm performance audit + +Date: 2026-10-03. Production baseline: `4d312c4e`. Optimized implementation: +`766c3965`. Work was isolated in `codex/memory-algorithm-performance`. + +[中文报告](../zh/development/memory-algorithm-performance.md) + +This audit covers the native Memory read/write pipeline: SQLite retrieval, +keyword and vector scoring, multi-signal recall, semantic candidates, bounded +graph traversal, graph writes and retention. Agency authorization, replay and +daemon protocols are outside this change. There is no claim of a universally +optimal implementation: input size, graph density, selectivity and durability +requirements impose different costs. + +## What changed + +1. Replace three single-column insight indexes with indexes matching active + timestamp, source/timestamp and importance/timestamp reads. Remove the old + indexes so writes do not maintain both sets. Query-plan tests verify that + these ordered reads no longer need a temporary sort. Existing stores upgrade + on writable open; read-only stores continue to work without migration. +2. Load bounded BFS neighborhoods through endpoint indexes, keeping edge + insertion order, self-loop deduplication, deleted-node filtering, depth and + result limits. Unlimited traversal retains bulk loading. Typed neighborhood + reads use two indexed branches: a factored OR can otherwise make SQLite scan + every edge of the requested type. +3. Keep per-query keyword and cosine **scores** instead of retaining every token + set and embedding vector. Stream embedding blobs, compute cosine once per + vector and reuse it across anchor selection, beam traversal and reranking. + Reuse already-loaded active insights and cache successful adjacency reads, + including empty neighborhoods, across anchors. Caches die with the query. +4. Keep only the best K semantic or embedding-only diff candidates with a typed + heap. Reuse tokenization of the query in semantic token fallback, and merge + content/tag/entity tokens directly without allocating separate field maps. +5. Reuse SQL's time ordering when it also matches absolute timestamp ordering; + imported timestamps with different UTC offsets still get the original sort. +6. Skip known-entity extraction scans in explicitly provided entity mode. + Prepare insight/edge inserts once per transaction and reuse the statements. + The transaction closes them on commit/rollback; panic cleanup also rolls back + before clearing the transaction-local pointers. + +The scoring formulas, weights, similarity thresholds, RRF constant, anchor +limits, per-anchor visited sets, beam budgets, supersession demotion, exact +duplicate identity checks, causal ordering and embedding failure fallback are +unchanged. Equal-score/equal-time candidates still have no guaranteed relative +order; the old code already combined unordered maps and non-stable sorts. The +optimization does not add approximate nearest-neighbor search or discard +low-ranked candidates before a stage that needs them for score normalization. + +## Complexity audit + +Let **N** be active insights, **E** graph edges, **L** average text/tag/entity +size, **d** embedding dimensions, **Q** query tokens and **K** requested results. +**M** is the number of matching rows examined by a filtered SQL read. Hash-map +lookups below use expected constant time. Key/payload sizes matter in addition +to the row count. + +| Path | Before | After / remaining cost | +|---|---|---| +| ID lookup | B-tree `O(log N)` plus payload decoding | Unchanged control | +| All active insights, sorted by time | `O(N log N + NL)` with temporary sort | `O(N + NL)` ordered index scan | +| Latest/recent by source; unfiltered ranked LIMIT | Scan matching rows and order them; bounded SQLite LIMIT sorting can be `O(M log K)`, latest-one is `O(M)` | `O(log N + K)` for these index-compatible predicates, plus returned payloads | +| Leading-wildcard LIKE / other residual filters | Worst-case scan of candidates | Still worst-case `O(NL)`; an ordering index cannot prove a negative substring match | +| Entity membership in JSON | Inspect matching JSON entries and order candidates | Can stop after K matches in time order; a miss still visits all N rows and their entity entries. No entity inverted index was introduced | +| Keyword ranking | `O(N(L + Q + log K))` | Same asymptotic bound, fewer allocations; recall retains N scalar scores instead of N token sets | +| Exact vector anchor search | `O(Nd + N log K)` | Same exact search bound; computed cosine scores are reused by downstream stages | +| Semantic candidates / embedding-only diff selection | `O(Nd + M log M)` and `O(M)` selection storage | `O(Nd + M log K + K log K)` and `O(K)` selection storage | +| Semantic token fallback | Re-tokenize both texts per pair, then `O(M log M)` sort | Query tokenized once; `O(NL + M log K + K log K)`. Loading all active insights remains linear | +| RRF and time anchors | Combine at most 60 anchors; copy and sort N timestamps | RRF unchanged; `O(N)` order check with no copy for normal UTC data. Mixed-offset fallback remains `O(N log N)` | +| Final reranking / WHY ordering | Candidate scoring plus `O(C log C)` ranking and causal ordering | Ranking and ordering retained. Keyword/cosine signals reused; superseded lookup stays scoped to candidates and fail-closed | +| WHY topological ordering | Indexed outgoing-edge reads, then a heap-based Kahn traversal | Unchanged: `O(C log E + E_out + C log C)` for C returned nodes and their outgoing causal edges; cycles retain the existing fallback | +| Atomic batch of B inserts | B SQL compilations plus B-tree/JSON/durable write costs | One compilation per insert kind per transaction; still `O(B log(N+B))` index work, plus payload and commit I/O | +| Known-entity set / statistics | Whole-store JSON/aggregate scans | Unchanged when required; provided-entity mode avoids the unused scan | +| Retention refresh | Load N rows, aggregate E edges, compute scores, update N rows, sort candidates | Unchanged scan/update work; generally `O(E + N log N)` with current indexes and bounded payload sizes | +| Automatic capacity pruning | Count active rows, select eligible weakest records, then delete/audit a bounded batch | Active count remains `O(N)`; candidate selection can scan/sort eligible rows. Age, immunity, exclusions and atomic audit writes are unchanged | +| Single-vector cosine / serialization | `O(d)` / linear payload size | Unchanged; avoiding repeated calls provides the improvement | +| Batch import with per-item diff/semantic matching | Repeated exact scans as the corpus grows | Still potentially `O(BN + B²)` for fixed text/vector sizes; this PR reduces component costs, not the exact comparison requirement | + +For beam search, let **A <= 60** be anchors, **P** node expansions across all +anchors, **U <= P** distinct expanded nodes, **X** processed transitions and +**E_U** the sum of incident edges loaded for those distinct nodes. The original +path issued up to P adjacency queries, reloaded candidate insights and computed +cosine during each transition and final reranking. The new path issues at most +U successful adjacency queries, uses the active insight snapshot already loaded +at recall start and computes each cosine once. The cosine component changes from +`O((N + X + C)d)` to `O(Nd + X + C)`. Heap traversal itself is unchanged. P is +bounded by the existing depth, beam width and per-anchor visit budgets; dense +adjacency lists still cost time to read. Cached adjacency consumes `O(E_U)` +space, in addition to the active insight snapshot and `O(N)` scalar caches. + +For a bounded BFS, let **V_b** be expanded nodes, **R_b** distinct encountered +neighbors and **deg(v)** their incident degrees. Full-store loading is replaced +by approximately `O(V_b log E + sum(deg(v) log deg(v)) + R_b log N)` indexed work, +plus payloads. The degree sort preserves the old insertion order. Work depends +on the neighborhood, including missing/deleted endpoints, rather than unrelated +history. A high-degree node can still be expensive. Unlimited BFS retains its +bulk `O(NL + E)` loading and traversal path. + +## Measurement method + +The committed [benchmarks](../../internal/memory/performance_test.go) use real +temporary SQLite WAL databases and synthetic local vectors. N is **corpus size**, +not Go's adaptive benchmark iteration count. Sizes are 1, 10, 100, 1,000 and +10,000. There are 128 vector dimensions, fixed-width record IDs/text, two tags, +two entities and ten sources. The regular graph is a causal chain with N-1 +edges. A separate dense fixture at N=1/10/100 adds N(N-1) semantic edges. + +Read limits are 10, semantic candidate limits remain 3/5 and bounded BFS uses +two hops / 20 results. Entity-hit records all contain `SQLite`; `EntityMiss` and +`RankedKeywordMiss` deliberately scan for absent terms. Pure scoring benchmarks +start with inputs already in memory; recall/BFS include their database reads. +Fixtures use historical timestamps, so EngineProvided measures backbone, +entity and semantic work without current-window proximity edges. It replaces +existing edges inside a transaction, keeping the graph size bounded. + +Insert measures N new insights into an empty store in one committed transaction; +fixture construction and cleanup are excluded. Retention includes its existing +effective-importance writes. None of these timings include CLI startup, +provider/network latency, embedding generation or a cold filesystem cache. + +Host: Apple M4, Darwin/arm64, Go 1.25.4, `-cpu=1`. The same benchmark sources were +compiled against each production revision. Five independent runs per revision +used `-benchtime=100ms`, alternating before/after order between rounds. Tables +show medians. `cpu-ns/op` is process user+system CPU, including GC, measured with +`getrusage`; it excludes descheduling and blocked I/O. Ordinary `ns/op` remains +wall time. The insert benchmark excludes cleanup from both metrics. Other OSes +still run the benchmarks with wall-time/allocation reporting. + +The machine was shared, not an isolated performance lab. CPU measurements, +unchanged control paths, allocation counts, query plans and operation counts +are used together; timing ratios are local observations, not latency promises. +`B/op` is cumulative Go allocation per operation, **not peak RSS** or database +file size. Three timing points alone cannot establish a Big-O bound. + +### N=1, 10, 100 + +CPU **µs/op**, before → after. Each cell is a median of five runs. + +| Path | N=1 | N=10 | N=100 | +|---|---:|---:|---:| +| ByID | 10.2 → 10.5 | 10.2 → 10.1 | 10.2 → 10.2 | +| AllActive | 11.2 → 11.3 | 32.9 → 30.7 | 259.4 → 210.1 | +| Ranked | 22.7 → 21.1 | 44.5 → 40.5 | 52.9 → 40.1 | +| SourceLatest | 15.9 → 14.2 | 15.8 → 14.5 | 24.0 → 14.3 | +| SourceRecent | 23.2 → 22.6 | 23.6 → 22.9 | 48.6 → 41.6 | +| Entity | 16.7 → 16.2 | 25.4 → 23.1 | 100.9 → 26.1 | +| EntityMiss | 16.1 → 15.9 | 20.8 → 19.9 | 67.5 → 62.5 | +| RankedKeywordMiss | 22.9 → 21.6 | 25.6 → 24.4 | 59.2 → 55.3 | +| Embeddings | 6.0 → 6.4 | 14.3 → 14.2 | 87.7 → 88.1 | +| Keyword | 4.2 → 3.4 | 37.8 → 30.4 | 355.8 → 290.2 | +| Diff | 7.3 → 6.2 | 74.7 → 64.4 | 440.9 → 368.9 | +| RecallKeyword | 70.9 → 67.8 | 877.3 → 266.4 | 4,839.2 → 2,094.4 | +| RecallHybrid | 78.2 → 75.6 | 919.5 → 283.5 | 6,144.7 → 2,253.8 | +| RecallWhy | 43.7 → 42.0 | 1,121.4 → 344.5 | 7,561.7 → 2,357.0 | +| SemanticEmbedding | 11.5 → 13.1 | 53.5 → 53.0 | 70.6 → 63.2 | +| SemanticTokens | 11.5 → 13.1 | 76.9 → 51.0 | 676.6 → 407.8 | +| Neighborhood | 17.0 → 14.8 | 49.4 → 57.7 | 359.3 → 58.8 | +| Atomic insert batch | 74.8 → 75.0 | 266.4 → 171.7 | 2,246.0 → 1,203.7 | +| KnownEntities | 8.0 → 8.4 | 15.4 → 15.6 | 69.3 → 69.3 | +| Retention | 58.2 → 59.0 | 151.9 → 149.6 | 1,134.6 → 1,104.2 | +| EngineProvided | 97.0 → 85.8 | 388.3 → 300.7 | 1,004.4 → 637.8 | + +### Larger corpus and allocation results + +CPU **ms/op**, before → after; allocation is **KiB/op** at N=10,000. Speedup is before CPU / after CPU, not a throughput SLA. + +| Path | N=1,000 CPU | N=10,000 CPU | Speedup at 10,000 | Allocation at 10,000 | +|---|---:|---:|---:|---:| +| ByID | 0.010 → 0.010 | 0.011 → 0.010 | 1.05× | 2.3 → 2.3 | +| AllActive | 2.449 → 1.976 | 36.536 → 21.287 | 1.72× | 14,914.0 → 14,913.3 | +| Ranked | 0.123 → 0.039 | 2.294 → 0.040 | 57.33× | 15.9 → 15.9 | +| SourceLatest | 0.070 → 0.015 | 1.193 → 0.015 | 81.60× | 2.4 → 2.4 | +| SourceRecent | 0.098 → 0.042 | 1.169 → 0.042 | 27.85× | 15.8 → 15.8 | +| Entity | 0.948 → 0.023 | 18.365 → 0.024 | 779.19× | 1.5 → 1.5 | +| EntityMiss | 0.499 → 0.468 | 10.710 → 6.614 | 1.62× | 0.6 → 0.6 | +| RankedKeywordMiss | 0.375 → 0.372 | 9.417 → 9.796 | 0.96× | 1.3 → 1.3 | +| Embeddings | 0.800 → 0.805 | 14.801 → 14.857 | 1.00× | 16,160.0 → 16,160.0 | +| Keyword | 3.524 → 2.814 | 33.609 → 27.180 | 1.24× | 33,438.9 → 19,688.6 | +| Diff | 4.106 → 3.043 | 35.969 → 28.939 | 1.24× | 35,175.5 → 20,903.8 | +| RecallKeyword | 10.548 → 6.443 | 76.940 → 53.769 | 1.43× | 49,681.0 → 35,820.2 | +| RecallHybrid | 15.744 → 9.435 | 101.097 → 73.694 | 1.37× | 77,488.4 → 58,103.1 | +| RecallWhy | 17.782 → 10.200 | 108.947 → 75.466 | 1.44× | 77,854.1 → 58,215.7 | +| SemanticEmbedding | 0.221 → 0.144 | 1.892 → 0.962 | 1.97× | 966.1 → 12.4 | +| SemanticTokens | 6.516 → 3.933 | 75.362 → 41.223 | 1.83× | 42,593.3 → 22,179.5 | +| Neighborhood | 3.362 → 0.058 | 45.634 → 0.058 | 782.60× | 23,425.1 → 9.3 | +| Atomic insert batch | 42.133 → 35.761 | 550.995 → 458.416 | 1.20× | 12,970.7 → 11,017.7 | +| KnownEntities | 0.584 → 0.581 | 11.751 → 11.645 | 1.01× | 1.5 → 1.5 | +| Retention | 11.675 → 11.813 | 184.412 → 185.037 | 1.00× | 20,025.9 → 20,025.9 | +| EngineProvided | 3.369 → 0.814 | 56.044 → 2.029 | 27.62× | 290.9 → 51.4 | + +### Dense graph and unchanged controls + +| Dense recall | CPU ms/op, before → after | CPU speedup | KiB/op, before → after | +|---|---:|---:|---:| +| N=1 | 0.059 → 0.058 | 1.02× | 11.2 → 9.8 | +| N=10 | 3.515 → 0.506 | 6.94× | 1,447.7 → 236.9 | +| N=100 | 126.394 → 19.429 | 6.51× | 66,880.2 → 10,048.0 | + +At N=10,000, unchanged ID lookup and embedding loading are approximately +1.05× and 1.00×, and retention remains approximately 1.00×. These controls +help distinguish the larger algorithmic gains from timing noise. Negative LIKE +lookup remains linear and used about 4% more CPU in this run. At N=10, bounded +BFS uses 57.7 µs versus 49.4 µs for the bulk baseline: extra indexed calls cost +more on tiny graphs. Single-record semantic lookup also has roughly 1.6 µs of +extra fixed overhead. These regressions are included, not removed from the data. + +The larger indexes initially increased batch-write CPU cost. Transaction-local +statement reuse brought the final 10,000-row batch from 551.0 ms to 458.4 ms +(about 17% less CPU) with the same commit boundary. Hybrid recall reduced +per-operation allocation from about 75.7 MiB to 56.7 MiB; dense recall at N=100 +dropped from about 65.3 MiB to 9.8 MiB. Bounded neighborhood allocation at +N=10,000 is 9,504 bytes rather than 23,987,320 bytes. + +The selector's deterministic comparison-count test forces an eviction for every +new item once K=5 is full. Counts at N=1/10/100/1,000/10,000 are +**0 / 37 / 440 / 4,491 / 44,991**, including final sorting of K items. This supports +the code-derived `O(N log K)` bound without a flaky wall-clock CI assertion. + +The complete five-run output for every path, including controls and misses, is +saved as [before](benchmarks/2026-10-03-memory-before.txt) and +[after](benchmarks/2026-10-03-memory-after.txt). No exploratory or superseded +implementation measurements are mixed into these files. + +## Correctness and verification + +- `go build -o mnemon .` — passed. +- `make test` — passed, including vet, deterministic tests and architecture + checks. The pure Memory-local top-K leaf is included in the dependency graph + and regular deterministic test list. +- `go test -race ./internal/memory/... ./cmd/memory -count=1` — passed. +- `MNEMON_EMBED_ENDPOINT=http://127.0.0.1:1 bash scripts/e2e_test.sh` — all + **258 assertions passed**, with embedding providers unavailable by design. +- Cached traversal is checked against the previous independent implementation + for all four intents, multiple budgets, multiple anchors, cyclic graphs, + deleted nodes and mismatched vector dimensions. Scores and via labels agree. +- Indexed bounded BFS is compared with bulk traversal, including order, hop, + edge identity, limits, filters, self-loops and missing/deleted endpoints. +- Tests cover top-K/full-sort parity, comparison bounds, token-field boundaries, + request refresh after vector/edge/deletion changes, mixed timestamp offsets, + index upgrades/reopens, endpoint query plans, transaction commit/rollback, + statement reuse, edge replacement and panic cleanup. + +The Agency/Docker/provider integration umbrella and paid live suite were not +run; these changes do not modify those boundaries. The Memory CLI boundary was +exercised directly. The changes do not add goroutines or change transaction +commit policy, supersession authority or exact-duplicate write suppression. + +## Reproduce + +On the PR revision: + +```sh +go test ./internal/memory -run '^$' -bench BenchmarkMemory \ + -benchmem -benchtime=100ms -count=5 -cpu=1 +go test ./internal/memory/internal/topk -run TestComparisonBudget -v +go test ./internal/memory/store -run 'Test(ActiveReadPlans|TraversalReadPlans)' -v +``` + +For a matched baseline, extract `4d312c4e` into a temporary directory and copy +only `internal/memory/performance*test.go` from this PR into its +`internal/memory/` directory. Compile both with +`go test -c -o ./internal/memory`, then run the binaries +with `-test.run='^$' -test.bench=BenchmarkMemory -test.benchmem +-test.benchtime=100ms -test.count=1 -test.cpu=1` in alternating order for five +rounds. Compare medians of the identically named cases. Do not run other test +suites concurrently with the measurements. + +## Remaining limits + +Exact keyword/vector matching, JSON entity misses and retention still have +whole-corpus work. Persistent token/entity indexes would need their own +migration, update/delete/rollback and tokenization parity contracts. An ANN +index would additionally need a recall-quality budget, which this task did not +permit sacrificing. Larger composite keys trade some insertion work/storage +for ordered reads; transaction-local statement reuse offsets compilation work, +but does not make durable writes constant-time. Large or unbounded graph walks +still depend on actual graph density. These costs are kept explicit rather than +hidden behind a cache that can become stale between commands. diff --git a/docs/zh/development/memory-algorithm-performance.md b/docs/zh/development/memory-algorithm-performance.md new file mode 100644 index 00000000..d9561854 --- /dev/null +++ b/docs/zh/development/memory-algorithm-performance.md @@ -0,0 +1,94 @@ +# Memory 算法性能调优报告 + +日期:2026-10-03。在独立 worktree、分支 +`codex/memory-algorithm-performance` 中完成。基线为 `4d312c4e`,最终算法实现为 +`766c3965`。范围覆盖 Memory 的查询、存储、关键词/向量召回、图遍历、语义候选和 +保留策略;不修改 Agency 的授权、重放或 daemon 协议。 + +[完整复杂度分析、全部测试表格、原始数据和复现方式](../../development/memory-algorithm-performance.md) +保存在英文报告中。 + +## 结论 + +可以在保持评分公式、阈值、遍历预算、过期内容降权和事务提交规则的前提下继续优化。 +本次主要消除了重复读取、重复评分、无必要的全量排序和逐行 SQL 编译。没有引入 +近似向量检索,也没有用缩减候选数量的方式牺牲召回质量。 + +不能把这理解为所有路径都达到“绝对最优”:精确向量匹配仍需扫描向量,实体与 +子串未命中仍可能扫描全库,持久化和图密度也有实际成本。报告区分了复杂度下降、 +常数优化和未改变的成本。 + +## N=1、10、100 的验证 + +N 表示活跃记录数,不是重复运行次数。以下是单次操作的 **CPU 微秒**,格式为 +“优化前 → 优化后”,取 5 轮中位数。 + +| 路径 | N=1 | N=10 | N=100 | +|---|---:|---:|---:| +| 关键词检索 | 4.2 → 3.4 | 37.8 → 30.4 | 355.8 → 290.2 | +| 混合召回 | 78.2 → 75.6 | 919.5 → 283.5 | 6,144.7 → 2,253.8 | +| WHY 召回 | 43.7 → 42.0 | 1,121.4 → 344.5 | 7,561.7 → 2,357.0 | +| 两跳邻域 | 17.0 → 14.8 | 49.4 → 57.7 | 359.3 → 58.8 | +| N 条记录的原子插入 | 74.8 → 75.0 | 266.4 → 171.7 | 2,246.0 → 1,203.7 | + +另外测试了 N=1,000、10,000,避免用小样本的固定开销推断复杂度。N=10,000 的 +结果如下,单位为 **CPU 毫秒**;倍数是前后 CPU 时间之比。 + +| 路径 | 优化前 | 优化后 | 倍数 | +|---|---:|---:|---:| +| 按来源取最新记录 | 1.193 | 0.0146 | 81.60× | +| 按重要性取前 10 条 | 2.294 | 0.040 | 57.33× | +| 混合召回 | 101.097 | 73.694 | 1.37× | +| 向量语义候选 | 1.892 | 0.962 | 1.97× | +| 两跳邻域 | 45.634 | 0.0583 | 782.60× | +| 10,000 条原子插入 | 550.995 | 458.416 | 1.20× | +| 显式提供实体的图写入流程 | 56.044 | 2.029 | 27.62× | + +额外的稠密图测试在 N=100 时,混合召回从 126.394 ms 降到 19.429 ms,约 6.51×。 +每次分配从约 65.3 MiB 降到 9.8 MiB。普通 N=10,000 混合召回的每次分配从约 +75.7 MiB 降到 56.7 MiB;局部邻域从 23,987,320 字节降到 9,504 字节。 +这些是累计分配量,不是进程峰值内存。 + +## 实施的优化与复杂度 + +- **有序数据库查询**:用活跃记录的时间、来源/时间、重要性/时间复合索引替换三个 + 单列索引。匹配这些索引的有限查询从扫描候选并排序,变为约 `O(log N + K)`; + 全部活跃记录的时间排序读取从 `O(N log N)` 的排序成本降为线性索引遍历。 +- **局部图遍历**:有限 BFS 只读取实际邻域,不再先加载全部 N 条记录和 E 条边。 + 保留边的插入顺序、类型过滤、最大跳数、数量限制和删除过滤。无限遍历仍批量加载, + 避免把全图遍历变成逐节点 SQL 查询。 +- **多路召回**:关键词与余弦相似度只计算一次,保存标量分数;同一请求的多个锚点 + 共用邻接查询结果和已加载的记录。每个锚点仍有独立的 visited 集合及预算。 + 假设 X 次图转移、d 维向量,重复余弦计算的主要成本由 `O((N+X)d)` 降为 + `O(Nd+X)`。缓存随请求结束,不跨命令保留过期状态。 +- **语义候选与 Diff**:前 K 名选择由全量排序改为有界堆,选择成本从 + `O(M log M)` 降为 `O(M log K)`,选择存储从 `O(M)` 降为 `O(K)`。 + K=5 时,N=1/10/100/1,000/10,000 的比较次数实测为 + 0/37/440/4,491/44,991;CI 检查操作次数上界,不以脆弱的计时阈值判定成功。 +- **写入**:事务内按需预编译并复用记录/边插入语句,提交或回滚后释放。 + 批量插入仍有 `O(B log(N+B))` 的索引工作,但不再为每行重复编译相同 SQL。 + 显式提供实体时跳过无用途的全库实体提取。 + +固定查询与结果限额下,关键词检索仍随文本总量线性增长;精确向量扫描仍是 +`O(Nd)`。保留策略刷新仍需聚合边、更新记录、排序候选,一般为 `O(E+N log N)`。 +自动裁剪的活跃计数仍有 `O(N)` 成本。逐条精确比对的批量导入仍可能有 +`O(BN+B²)` 的累计工作。这些路径没有被包装成“常数时间”。 + +## 取舍、测量与验证 + +测试使用 Apple M4、Go 1.25.4、单 P、真实临时 SQLite WAL 数据库和 128 维本地 +合成向量,交替运行前后版本。记录实际耗时、进程 CPU 时间及分配量,共 +108 个用例 × 5 轮 × 2 个版本。不调用付费模型,不计入 CLI 启动、网络和冷缓存。 +机器是共享开发环境,所以这些数字是本机观测,不能直接作为线上延迟承诺。 + +小规模存在固定开销取舍:N=10 的局部 BFS 多约 8.3 µs;单条语义查询多约 +1.6 µs。N=10,000 的未命中 LIKE 查询仍是线性扫描,本轮 CPU 约慢 4%。 +这些结果均保留在报告中。更宽的索引最初增加了批量写入成本;加入事务内语句复用后, +最终 10,000 条插入的 CPU 比基线减少约 17%。 + +已通过单文件产品构建、`make test`、Memory 和命令层的 race 测试,以及全部 +258 项 CLI E2E 断言。新增测试覆盖四种意图与预算下的新旧遍历等价性、图环路、 +已删除/缺失节点、查询间缓存刷新、跨时区排序、索引迁移、事务回滚和 panic 清理。 +原有等分/同时间候选的相对顺序没有确定性保证,本次也不作逐字节排序不变的承诺。 + +没有运行不受本次改动影响的 Agency/Docker 集成总入口和付费 live 套件。 From 9393edbe4bc29e4c7068dc672e4f52b85fbd4e2e Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 19:31:16 +0800 Subject: [PATCH 7/8] refactor(memory): reuse vector decode buffers during recall Decode each stored vector into a request-local reusable buffer before retaining its scalar cosine score. Keep one float32 decoder and preserve the existing arithmetic, invalid-input behavior and query lifetime. Validated buffer growth, shrinkage and special float encodings, upstream traversal parity, the product build, make test, Memory race tests and all 258 CLI E2E assertions. A paired 10,000-record probe reduced hybrid recall allocation by about 10.24 MB per operation. --- internal/memory/embed/vector.go | 20 +++++++++--- internal/memory/embed/vector_test.go | 43 ++++++++++++++++++++++++++ internal/memory/search/recall_cache.go | 5 ++- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/internal/memory/embed/vector.go b/internal/memory/embed/vector.go index 3e4251a5..f60e3f5f 100644 --- a/internal/memory/embed/vector.go +++ b/internal/memory/embed/vector.go @@ -36,14 +36,26 @@ func SerializeVector(v []float64) []byte { // DeserializeVector decodes a little-endian float32 blob into a float64 slice. func DeserializeVector(b []byte) []float64 { + return DeserializeVectorInto(b, nil) +} + +// DeserializeVectorInto decodes the same format as DeserializeVector, reusing +// dst's backing array when it has enough capacity. The caller owns that array +// and must consume its contents before reusing it. Invalid blobs return nil. +func DeserializeVectorInto(b []byte, dst []float64) []float64 { if len(b) == 0 || len(b)%4 != 0 { return nil } - v := make([]float64, len(b)/4) - for i := range v { - v[i] = float64(math.Float32frombits(binary.LittleEndian.Uint32(b[i*4:]))) + n := len(b) / 4 + if cap(dst) < n { + dst = make([]float64, n) + } else { + dst = dst[:n] } - return v + for i := range dst { + dst[i] = float64(math.Float32frombits(binary.LittleEndian.Uint32(b[i*4:]))) + } + return dst } // DeserializeLegacyVector decodes a pre-migration little-endian float64 blob. diff --git a/internal/memory/embed/vector_test.go b/internal/memory/embed/vector_test.go index 6432a8b0..1b8e9763 100644 --- a/internal/memory/embed/vector_test.go +++ b/internal/memory/embed/vector_test.go @@ -127,6 +127,49 @@ func TestDeserializeVector_InvalidLength(t *testing.T) { } } +func TestDeserializeVectorInto_ReusesCapacityAndResizes(t *testing.T) { + dst := make([]float64, 0, 4) + backing := &dst[:cap(dst)][0] + for _, input := range [][]float64{{1, -2, 3}, {4}, {5, 6, 7, 8}, {9, 10, 11, 12, 13}, {-14, 15}} { + oldCapacity := cap(dst) + dst = DeserializeVectorInto(SerializeVector(input), dst) + if len(dst) != len(input) { + t.Fatalf("decoded length = %d, want %d", len(dst), len(input)) + } + if len(input) <= oldCapacity && &dst[0] != backing { + t.Fatal("decoder did not reuse available capacity") + } + for i, want := range input { + if dst[i] != want { + t.Fatalf("decoded[%d] = %v, want %v", i, dst[i], want) + } + } + backing = &dst[0] + } + for _, blob := range [][]byte{nil, {}, {1}, {1, 2, 3, 4, 5}} { + if got := DeserializeVectorInto(blob, dst); got != nil { + t.Fatalf("invalid blob returned stale vector: %v", got) + } + } +} + +func TestDeserializeVectorInto_PreservesFloatBits(t *testing.T) { + // Include subnormal, signed zero, infinity and NaN encodings as well as + // normal values. Buffer reuse must not change float32-to-float64 decoding. + bits := []uint32{0, 1, 0x80000000, 0x3f800000, 0xbf800000, 0x7f7fffff, 0x7f800000, 0xff800000, 0x7fc00001} + blob := make([]byte, len(bits)*4) + for i, value := range bits { + binary.LittleEndian.PutUint32(blob[i*4:], value) + } + got := DeserializeVectorInto(blob, make([]float64, len(bits))) + for i, value := range bits { + want := float64(math.Float32frombits(value)) + if math.Float64bits(got[i]) != math.Float64bits(want) { + t.Fatalf("float bits changed at %d: got %x want %x", i, math.Float64bits(got[i]), math.Float64bits(want)) + } + } +} + func TestDeserializeLegacyVector_InvalidLength(t *testing.T) { if v := DeserializeLegacyVector(make([]byte, 7)); v != nil { t.Errorf("invalid legacy blob length: want nil, got %v", v) diff --git a/internal/memory/search/recall_cache.go b/internal/memory/search/recall_cache.go index 96252108..76a7f549 100644 --- a/internal/memory/search/recall_cache.go +++ b/internal/memory/search/recall_cache.go @@ -48,9 +48,12 @@ func (c *recallCache) transitionsFor(id string) ([]recallTransition, error) { func loadQuerySimilarities(db *store.DB, queryVec []float64) map[string]float64 { scores := make(map[string]float64) + var decoded []float64 // The callback only computes a scalar; it never re-enters the single-conn DB. + // Consume each vector immediately so the next row can reuse its decode buffer. err := db.ScanEmbeddings(func(id string, blob []byte) bool { - if vec := embed.DeserializeVector(blob); vec != nil { + if vec := embed.DeserializeVectorInto(blob, decoded); vec != nil { + decoded = vec scores[id] = embed.CosineSimilarity(queryVec, vec) } return true From 30d61deb2d47a89cac954b18157c08897a7ccc5b Mon Sep 17 00:00:00 2001 From: GRIVN Date: Sat, 3 Oct 2026 19:36:17 +0800 Subject: [PATCH 8/8] docs(memory): remeasure performance against current master Compare the merged implementation with master at 5c98ff9c using 1,080 fresh alternating benchmark samples. Attribute upstream transition caching separately, document the decode-buffer allocation reduction, and retain small-input regressions and exact-search complexity limits. Update the English and Chinese reports with current traversal parity and local validation results. Preserve the original experiment as historical evidence and include the separate decode-buffer probe. --- .../2026-10-03-memory-decode-after.txt | 29 + .../2026-10-03-memory-decode-before.txt | 29 + .../benchmarks/2026-10-03-memory-main.txt | 581 ++++++++++++++++++ .../benchmarks/2026-10-03-memory-synced.txt | 581 ++++++++++++++++++ .../memory-algorithm-performance.md | 193 +++++- .../memory-algorithm-performance.md | 171 +++--- 6 files changed, 1491 insertions(+), 93 deletions(-) create mode 100644 docs/development/benchmarks/2026-10-03-memory-decode-after.txt create mode 100644 docs/development/benchmarks/2026-10-03-memory-decode-before.txt create mode 100644 docs/development/benchmarks/2026-10-03-memory-main.txt create mode 100644 docs/development/benchmarks/2026-10-03-memory-synced.txt diff --git a/docs/development/benchmarks/2026-10-03-memory-decode-after.txt b/docs/development/benchmarks/2026-10-03-memory-decode-after.txt new file mode 100644 index 00000000..9c4c5d50 --- /dev/null +++ b/docs/development/benchmarks/2026-10-03-memory-decode-after.txt @@ -0,0 +1,29 @@ +# Isolated vector decode buffer comparison, 2026-10-03 +# Production commit: 9393edbe4bc29e4c7068dc672e4f52b85fbd4e2e +# Benchmark sources: a21d783b; Apple M4; darwin/arm64; Go 1.25.4 +# Three alternating rounds; N=10000; RecallHybrid and RecallWhy +# -test.bench=^BenchmarkMemoryRead$/^N=10000$/^(RecallHybrid|RecallWhy)$ +# -test.run=^$ -test.benchtime=200ms -test.cpu=1 -test.benchmem +# No other local tests ran concurrently; cumulative B/op is not peak RSS + +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=10000/RecallHybrid 4 65679614 ns/op 65520000 cpu-ns/op 49110548 B/op 906667 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 4 65544052 ns/op 65512250 cpu-ns/op 49180698 B/op 909459 allocs/op +PASS +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=10000/RecallHybrid 3 67077111 ns/op 67044333 cpu-ns/op 49103488 B/op 906507 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 4 66150698 ns/op 66126500 cpu-ns/op 49180458 B/op 909459 allocs/op +PASS +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=10000/RecallHybrid 4 63996958 ns/op 63850500 cpu-ns/op 49114596 B/op 906761 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 3 70158306 ns/op 69437333 cpu-ns/op 49179624 B/op 909421 allocs/op +PASS diff --git a/docs/development/benchmarks/2026-10-03-memory-decode-before.txt b/docs/development/benchmarks/2026-10-03-memory-decode-before.txt new file mode 100644 index 00000000..1a93cb04 --- /dev/null +++ b/docs/development/benchmarks/2026-10-03-memory-decode-before.txt @@ -0,0 +1,29 @@ +# Isolated vector decode buffer comparison, 2026-10-03 +# Production commit: 6d1511aca64bc9892aeee23a9e45c8f3486f98ab +# Benchmark sources: a21d783b; Apple M4; darwin/arm64; Go 1.25.4 +# Three alternating rounds; N=10000; RecallHybrid and RecallWhy +# -test.bench=^BenchmarkMemoryRead$/^N=10000$/^(RecallHybrid|RecallWhy)$ +# -test.run=^$ -test.benchtime=200ms -test.cpu=1 -test.benchmem +# No other local tests ran concurrently; cumulative B/op is not peak RSS + +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=10000/RecallHybrid 3 67769264 ns/op 65984000 cpu-ns/op 59354144 B/op 916762 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 3 68961611 ns/op 68912667 cpu-ns/op 59414122 B/op 919264 allocs/op +PASS +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=10000/RecallHybrid 3 69582194 ns/op 69488333 cpu-ns/op 59354224 B/op 916763 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 3 68606861 ns/op 68585333 cpu-ns/op 59418562 B/op 919419 allocs/op +PASS +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=10000/RecallHybrid 3 67607722 ns/op 67581667 cpu-ns/op 59348413 B/op 916635 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 3 69724722 ns/op 68933333 cpu-ns/op 59418562 B/op 919419 allocs/op +PASS diff --git a/docs/development/benchmarks/2026-10-03-memory-main.txt b/docs/development/benchmarks/2026-10-03-memory-main.txt new file mode 100644 index 00000000..e4587ab5 --- /dev/null +++ b/docs/development/benchmarks/2026-10-03-memory-main.txt @@ -0,0 +1,581 @@ +# Memory performance after syncing master; 2026-10-03 +# Production commit: 5c98ff9c08a7f9cbc8d6e1f374b542aa312468e9 +# Benchmark sources: a21d783b (identical performance*_test.go in both trees) +# Apple M4; darwin/arm64; Go 1.25.4; CPU includes user/system CPU and GC +# Five rounds, alternating version order; -test.cpu=1 -test.benchtime=100ms +# Wall time, cpu-ns/op, B/op and allocs/op; setup and cleanup excluded + +# Round 1; UTC 2026-10-03T11:31:16.278228+00:00; load (4.5380859375, 5.77783203125, 7.419921875) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 11222 10607 ns/op 10450 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11556 ns/op 11497 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5065 23198 ns/op 22881 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7618 16028 ns/op 16010 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5205 23938 ns/op 23857 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 5848 20326 ns/op 20106 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 6228 19440 ns/op 19380 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5187 22752 ns/op 22738 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19507 6110 ns/op 6097 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 26461 4505 ns/op 4448 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 15757 7611 ns/op 7522 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1450 74426 ns/op 74324 cpu-ns/op 8609 B/op 192 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1519 93405 ns/op 92178 cpu-ns/op 11657 B/op 222 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 1671 61503 ns/op 59390 cpu-ns/op 11512 B/op 216 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 13640 ns/op 13071 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11561 ns/op 11535 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 6249 17470 ns/op 17430 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10695 ns/op 10588 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 2653 57139 ns/op 37476 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2662 47643 ns/op 47273 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7336 16630 ns/op 16572 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5088 24315 ns/op 24213 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4612 26099 ns/op 26054 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5803 20947 ns/op 20836 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4514 26323 ns/op 26287 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 9981 19860 ns/op 18125 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 1966 54256 ns/op 44162 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1630 80686 ns/op 79102 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 378 319180 ns/op 318272 cpu-ns/op 90249 B/op 2012 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 351 359925 ns/op 356698 cpu-ns/op 118922 B/op 2179 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 264 455461 ns/op 455038 cpu-ns/op 140214 B/op 2722 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2354 54416 ns/op 54214 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1700 75584 ns/op 75054 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2467 50286 ns/op 50090 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10414 ns/op 10397 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 460 284063 ns/op 278511 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2594 51481 ns/op 51107 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5721 21937 ns/op 21843 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2808 47425 ns/op 47247 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1219 100253 ns/op 100014 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1755 65401 ns/op 65309 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2025 59253 ns/op 59071 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1210 93760 ns/op 92793 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 322 378863 ns/op 375677 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 256 474736 ns/op 470457 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 48 2772880 ns/op 2721354 cpu-ns/op 804738 B/op 16646 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 44 3046280 ns/op 3037523 cpu-ns/op 1136986 B/op 19756 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 43 3262873 ns/op 3243977 cpu-ns/op 1176535 B/op 20710 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1910 75874 ns/op 74565 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 170 699716 ns/op 696688 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 318 378005 ns/op 375541 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10584 ns/op 10562 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 54 2505343 ns/op 2495926 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 950 129575 ns/op 129465 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1660 72760 ns/op 72695 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1188 103822 ns/op 103233 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 97 1074747 ns/op 1046155 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 211 541840 ns/op 533052 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 298 397292 ns/op 395359 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 140 853521 ns/op 845614 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 33 4012481 ns/op 3857303 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 32 3917573 ns/op 3898156 cpu-ns/op 3631358 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 13 8442093 ns/op 8378538 cpu-ns/op 5357864 B/op 97656 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 9 13111356 ns/op 13023778 cpu-ns/op 8438714 B/op 119210 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 8 15657266 ns/op 15219875 cpu-ns/op 8530409 B/op 121842 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 499 246343 ns/op 241423 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 15 7318858 ns/op 7222133 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 38 3606123 ns/op 3580289 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10013 ns/op 10011 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 4 30420177 ns/op 30036500 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 122 978338 ns/op 979082 cpu-ns/op 16290 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 193 619550 ns/op 618098 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 177 668886 ns/op 669322 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 8 12626161 ns/op 12628500 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 20 5545694 ns/op 5547700 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 28 4039558 ns/op 4041536 cpu-ns/op 1276 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 10 10422783 ns/op 10408500 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 33688778 ns/op 33648667 cpu-ns/op 34241405 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 36349153 ns/op 36331667 cpu-ns/op 36019717 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 72580188 ns/op 72081000 cpu-ns/op 50788556 B/op 907733 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 91305020 ns/op 90775500 cpu-ns/op 78844276 B/op 1038035 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 89959542 ns/op 89375500 cpu-ns/op 78922032 B/op 1041042 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 66 1811833 ns/op 1811970 cpu-ns/op 989248 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 74015396 ns/op 73529500 cpu-ns/op 43615536 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 41644056 ns/op 40754333 cpu-ns/op 23987317 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1153 91223 ns/op 75302 cpu-ns/op 1723 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 390 288220 ns/op 278908 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 49 2767480 ns/op 2459714 cpu-ns/op 133187 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 45546722 ns/op 43951667 cpu-ns/op 1329253 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 551548167 ns/op 537519000 cpu-ns/op 13281848 B/op 300029 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14169 8427 ns/op 8384 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1533 125840 ns/op 70064 cpu-ns/op 3330 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 454 226088 ns/op 163236 cpu-ns/op 7677 B/op 176 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7338 15869 ns/op 15826 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 674 168881 ns/op 153528 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 278 437654 ns/op 416504 cpu-ns/op 24066 B/op 591 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1742 70380 ns/op 70224 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 102 1162086 ns/op 1129167 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 100 1084528 ns/op 1057010 cpu-ns/op 58112 B/op 1474 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 196 610040 ns/op 607689 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 8 12608557 ns/op 12335875 cpu-ns/op 1904826 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 32 3632917 ns/op 3580188 cpu-ns/op 73736 B/op 1528 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 14 7322417 ns/op 7301357 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 175561750 ns/op 171709000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 3 43367458 ns/op 42171000 cpu-ns/op 297810 B/op 1533 allocs/op +BenchmarkMemoryDenseRecall/N=1 1987 65659 ns/op 65326 cpu-ns/op 11353 B/op 209 allocs/op +BenchmarkMemoryDenseRecall/N=10 188 635461 ns/op 615654 cpu-ns/op 193359 B/op 4450 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 19239451 ns/op 19178667 cpu-ns/op 5680869 B/op 177375 allocs/op +PASS + +# Round 2; UTC 2026-10-03T11:32:06.863164+00:00; load (4.20361328125, 5.5126953125, 7.2275390625) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10709 ns/op 10686 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11643 ns/op 11567 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5383 24218 ns/op 23775 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 6548 17122 ns/op 16784 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5142 23657 ns/op 23627 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 6049 19735 ns/op 19547 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 6036 18813 ns/op 18814 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5206 22613 ns/op 22611 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19734 6045 ns/op 6034 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 28207 4231 ns/op 4210 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16490 7266 ns/op 7222 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1635 74466 ns/op 74390 cpu-ns/op 8609 B/op 192 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1527 88699 ns/op 86992 cpu-ns/op 11657 B/op 222 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2642 47755 ns/op 47715 cpu-ns/op 11512 B/op 216 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11583 ns/op 11572 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 12260 ns/op 12181 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 6996 18457 ns/op 18251 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10615 ns/op 10599 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4072 33437 ns/op 33340 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2883 45799 ns/op 45695 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7543 15989 ns/op 15987 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5089 23969 ns/op 23963 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4533 25683 ns/op 25660 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5678 20740 ns/op 20707 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4676 25477 ns/op 25462 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14009 ns/op 13926 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3259 37456 ns/op 37263 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1730 79979 ns/op 78161 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 340 339871 ns/op 336747 cpu-ns/op 90249 B/op 2012 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 356 341655 ns/op 340969 cpu-ns/op 118922 B/op 2179 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 267 443990 ns/op 443217 cpu-ns/op 140213 B/op 2722 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2433 53938 ns/op 53901 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1699 72948 ns/op 72702 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2467 50040 ns/op 49827 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10333 ns/op 10320 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 470 260532 ns/op 259628 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2601 49510 ns/op 49429 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5786 21024 ns/op 21017 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2890 46454 ns/op 46236 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1213 98256 ns/op 98312 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1845 64529 ns/op 64397 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2079 57478 ns/op 57488 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1272 91465 ns/op 90693 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 327 363894 ns/op 361554 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 272 444475 ns/op 442390 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 45 2607801 ns/op 2603444 cpu-ns/op 804737 B/op 16646 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 43 3158625 ns/op 3138977 cpu-ns/op 1136990 B/op 19756 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 39 3247786 ns/op 3236154 cpu-ns/op 1176537 B/op 20710 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1902 70394 ns/op 70283 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 162 719740 ns/op 710846 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 326 389857 ns/op 374887 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10247 ns/op 10249 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 54 2472959 ns/op 2452611 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 966 128003 ns/op 128019 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1694 71426 ns/op 71413 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1225 105919 ns/op 105119 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 94 1092565 ns/op 1023479 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 234 509014 ns/op 509158 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 301 389585 ns/op 388724 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 146 810738 ns/op 805788 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 34 3526445 ns/op 3513206 cpu-ns/op 3425395 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 31 3994337 ns/op 3950129 cpu-ns/op 3631396 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 13 7978375 ns/op 7969308 cpu-ns/op 5357842 B/op 97655 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 9 12336232 ns/op 12314778 cpu-ns/op 8438714 B/op 119210 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 12989611 ns/op 12965556 cpu-ns/op 8530378 B/op 121843 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 565 219984 ns/op 219768 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 18 6649928 ns/op 6627889 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 38 3476856 ns/op 3462868 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10040 ns/op 10043 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 4 29196240 ns/op 28744000 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 124 954072 ns/op 954379 cpu-ns/op 16290 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 199 599799 ns/op 599814 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 182 654983 ns/op 655341 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 8 12684151 ns/op 12675375 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 19 5428498 ns/op 5431211 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 27 4074562 ns/op 4075778 cpu-ns/op 1277 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 10 10168233 ns/op 10154000 cpu-ns/op 16547806 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 33839778 ns/op 33819667 cpu-ns/op 34241400 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 36596750 ns/op 36572667 cpu-ns/op 36019717 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 70085896 ns/op 69542000 cpu-ns/op 50788564 B/op 907733 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 89610229 ns/op 87870500 cpu-ns/op 78844276 B/op 1038035 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 92076917 ns/op 91085500 cpu-ns/op 78922032 B/op 1041042 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 67 1809438 ns/op 1809239 cpu-ns/op 989248 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 70561188 ns/op 70066000 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 44607681 ns/op 42395667 cpu-ns/op 23987317 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1126 95606 ns/op 76941 cpu-ns/op 1727 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 397 576681 ns/op 386277 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 51 2356113 ns/op 2291157 cpu-ns/op 133184 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 60298500 ns/op 51198333 cpu-ns/op 1329253 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 591878417 ns/op 551200000 cpu-ns/op 13281968 B/op 300030 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 15066 7969 ns/op 7967 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1478 79597 ns/op 61324 cpu-ns/op 3330 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1098 111878 ns/op 111836 cpu-ns/op 7364 B/op 174 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7899 15945 ns/op 15906 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 585 176222 ns/op 158176 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 285 419771 ns/op 399912 cpu-ns/op 24041 B/op 590 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1756 71303 ns/op 70800 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 92 1138351 ns/op 1107272 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 100 1061584 ns/op 1036730 cpu-ns/op 58132 B/op 1476 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 200 594814 ns/op 594760 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12204273 ns/op 11829556 cpu-ns/op 1904831 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 32 3547165 ns/op 3471438 cpu-ns/op 73706 B/op 1526 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 18 6528424 ns/op 6528556 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 174997625 ns/op 169215000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 2 50786584 ns/op 41295000 cpu-ns/op 297836 B/op 1534 allocs/op +BenchmarkMemoryDenseRecall/N=1 1977 64124 ns/op 64003 cpu-ns/op 11353 B/op 209 allocs/op +BenchmarkMemoryDenseRecall/N=10 228 526227 ns/op 525447 cpu-ns/op 193357 B/op 4450 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 18338319 ns/op 18318833 cpu-ns/op 5687053 B/op 177376 allocs/op +PASS + +# Round 3; UTC 2026-10-03T11:32:23.879573+00:00; load (4.7578125, 5.54541015625, 7.1982421875) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10355 ns/op 10340 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11308 ns/op 11307 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5442 22502 ns/op 22481 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7856 15795 ns/op 15786 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5308 23448 ns/op 23444 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 5803 19595 ns/op 19614 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 5881 19681 ns/op 19674 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5300 22579 ns/op 22578 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19407 6116 ns/op 6110 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 27182 4343 ns/op 4316 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16502 7284 ns/op 7252 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1666 75193 ns/op 74740 cpu-ns/op 8608 B/op 192 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1515 82219 ns/op 82186 cpu-ns/op 11657 B/op 222 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2724 47477 ns/op 47414 cpu-ns/op 11512 B/op 216 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11907 ns/op 11890 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11877 ns/op 11852 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 6895 17508 ns/op 17471 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10304 ns/op 10287 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4119 33384 ns/op 33175 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2667 45870 ns/op 45592 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7834 15853 ns/op 15850 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5383 23310 ns/op 23297 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4711 25624 ns/op 25614 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5703 20806 ns/op 20814 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4563 25647 ns/op 25636 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14338 ns/op 14257 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3214 37838 ns/op 37639 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1687 75896 ns/op 75365 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 363 328146 ns/op 325094 cpu-ns/op 90249 B/op 2012 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 357 337452 ns/op 336829 cpu-ns/op 118922 B/op 2179 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 262 455674 ns/op 453866 cpu-ns/op 140214 B/op 2722 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2464 53989 ns/op 53929 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1742 74036 ns/op 73774 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2403 49268 ns/op 49151 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10384 ns/op 10377 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 460 263077 ns/op 262350 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2624 50205 ns/op 50120 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5814 20954 ns/op 20956 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2886 45851 ns/op 45772 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1222 97739 ns/op 97777 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1872 65282 ns/op 65063 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2067 57844 ns/op 57873 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1262 91324 ns/op 90567 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 336 361564 ns/op 359610 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 243 517554 ns/op 501099 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 44 2875958 ns/op 2813636 cpu-ns/op 804739 B/op 16646 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 43 3312208 ns/op 3243791 cpu-ns/op 1136984 B/op 19756 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 42 3406709 ns/op 3328810 cpu-ns/op 1176533 B/op 20710 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1876 70648 ns/op 70625 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 177 674798 ns/op 672847 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 331 361214 ns/op 359625 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10444 ns/op 10439 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 52 2447042 ns/op 2434577 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 966 128187 ns/op 128138 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1662 72673 ns/op 72635 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1213 101859 ns/op 101721 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 123 963415 ns/op 962626 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 234 510424 ns/op 510534 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 310 388808 ns/op 388394 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 136 858842 ns/op 847757 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 38 3467782 ns/op 3455053 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 33 3749944 ns/op 3736333 cpu-ns/op 3631323 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 13 8041263 ns/op 8026462 cpu-ns/op 5357842 B/op 97655 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 9 12321931 ns/op 12291778 cpu-ns/op 8438714 B/op 119210 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 13473796 ns/op 13437889 cpu-ns/op 8530378 B/op 121843 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 560 225619 ns/op 224811 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 18 6589002 ns/op 6576889 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 38 3424647 ns/op 3415474 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10418 ns/op 10362 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 4 29885458 ns/op 29262500 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 124 952331 ns/op 952492 cpu-ns/op 16290 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 198 601329 ns/op 601606 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 182 656742 ns/op 656714 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 8 14053078 ns/op 13487000 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 20 5325281 ns/op 5326850 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 28 4037256 ns/op 4037929 cpu-ns/op 1276 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 10 10034888 ns/op 10016300 cpu-ns/op 16547801 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 33605347 ns/op 33593667 cpu-ns/op 34241394 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 35447264 ns/op 35433000 cpu-ns/op 36019717 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 70325146 ns/op 69980000 cpu-ns/op 50788556 B/op 907733 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 94820208 ns/op 93344000 cpu-ns/op 78853048 B/op 1038227 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 93286958 ns/op 92475000 cpu-ns/op 78922024 B/op 1041042 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 62 1979922 ns/op 1976484 cpu-ns/op 989249 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 73762750 ns/op 72947500 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 40791972 ns/op 40180333 cpu-ns/op 23987322 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1108 91556 ns/op 76112 cpu-ns/op 1712 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 396 300138 ns/op 276106 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 52 2291417 ns/op 2269365 cpu-ns/op 133186 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 40981584 ns/op 40656333 cpu-ns/op 1329216 B/op 30019 allocs/op +BenchmarkMemoryInsert/N=10000 1 505219042 ns/op 503905000 cpu-ns/op 13281720 B/op 300027 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 15036 7967 ns/op 7966 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1630 73284 ns/op 58725 cpu-ns/op 3299 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1128 109665 ns/op 109647 cpu-ns/op 7465 B/op 175 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7881 15808 ns/op 15808 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 668 169214 ns/op 154835 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 282 431423 ns/op 413968 cpu-ns/op 24061 B/op 591 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1755 68704 ns/op 68672 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 93 1156616 ns/op 1097452 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 100 1031372 ns/op 1009790 cpu-ns/op 58116 B/op 1475 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 199 600370 ns/op 600121 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12072421 ns/op 11844000 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 31 3527660 ns/op 3485839 cpu-ns/op 73693 B/op 1525 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 16 6704865 ns/op 6708625 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 174867875 ns/op 170104000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 3 37902500 ns/op 37832333 cpu-ns/op 297816 B/op 1535 allocs/op +BenchmarkMemoryDenseRecall/N=1 1962 62855 ns/op 62876 cpu-ns/op 11352 B/op 209 allocs/op +BenchmarkMemoryDenseRecall/N=10 230 517953 ns/op 517709 cpu-ns/op 193357 B/op 4450 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 21673326 ns/op 20550500 cpu-ns/op 5687048 B/op 177376 allocs/op +PASS + +# Round 4; UTC 2026-10-03T11:33:13.926534+00:00; load (3.953125, 5.236328125, 6.9892578125) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10324 ns/op 10241 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11354 ns/op 11303 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5415 22687 ns/op 22686 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7113 15954 ns/op 15936 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5288 24190 ns/op 24009 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 5869 20065 ns/op 19686 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 6265 19100 ns/op 19107 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5149 22758 ns/op 22715 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19789 6043 ns/op 6036 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 27910 4287 ns/op 4264 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 15636 7765 ns/op 7674 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1404 82534 ns/op 80721 cpu-ns/op 8609 B/op 192 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1507 82072 ns/op 82079 cpu-ns/op 11657 B/op 222 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2778 47910 ns/op 47851 cpu-ns/op 11512 B/op 216 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11433 ns/op 11425 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11821 ns/op 11747 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7221 17056 ns/op 17046 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10286 ns/op 10277 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4209 32574 ns/op 32498 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2918 45024 ns/op 44959 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7910 15882 ns/op 15878 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5094 24686 ns/op 24452 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4734 25198 ns/op 25199 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5748 21104 ns/op 21069 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4566 25763 ns/op 25761 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14330 ns/op 14235 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3121 37967 ns/op 37777 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1696 75030 ns/op 74713 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 380 309014 ns/op 308566 cpu-ns/op 90249 B/op 2012 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 361 339521 ns/op 338787 cpu-ns/op 118923 B/op 2179 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 267 448697 ns/op 448045 cpu-ns/op 140214 B/op 2722 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2396 53992 ns/op 53956 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1676 78411 ns/op 77402 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2395 54445 ns/op 53499 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 12364 ns/op 11907 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 429 284232 ns/op 281014 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2553 50332 ns/op 50211 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5881 21092 ns/op 21070 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2911 45842 ns/op 45771 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1216 97992 ns/op 98005 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1897 63951 ns/op 64014 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2097 57847 ns/op 57751 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1226 94610 ns/op 93542 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 327 393984 ns/op 385223 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 220 542224 ns/op 521532 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 48 2739750 ns/op 2699500 cpu-ns/op 804738 B/op 16646 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 44 3025897 ns/op 3004205 cpu-ns/op 1136985 B/op 19756 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 43 3146963 ns/op 3139395 cpu-ns/op 1176535 B/op 20710 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1912 70105 ns/op 70025 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 171 693546 ns/op 691567 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 330 369907 ns/op 368412 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10394 ns/op 10387 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 52 2428417 ns/op 2423481 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 974 127845 ns/op 127840 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1692 73072 ns/op 72780 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1065 107358 ns/op 105154 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 124 957980 ns/op 958339 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 236 512863 ns/op 512860 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 309 385493 ns/op 385605 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 144 826220 ns/op 821201 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 36 3634722 ns/op 3570917 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 30 4017388 ns/op 3983767 cpu-ns/op 3631435 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 13 10979375 ns/op 10010154 cpu-ns/op 5357852 B/op 97656 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 8 15238312 ns/op 13991750 cpu-ns/op 8435022 B/op 119209 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 8 13458662 ns/op 13434125 cpu-ns/op 8530428 B/op 121843 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 560 225314 ns/op 224891 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 15 6738992 ns/op 6726267 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 38 4822657 ns/op 4480053 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10156 ns/op 10142 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 4 32671958 ns/op 29820250 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 121 986419 ns/op 981215 cpu-ns/op 16290 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 195 606526 ns/op 606856 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 178 668819 ns/op 667916 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 8 13995292 ns/op 13887875 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 18 6330023 ns/op 6324444 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 24 4590085 ns/op 4585667 cpu-ns/op 1280 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 9 11450384 ns/op 11250444 cpu-ns/op 16547805 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 36340445 ns/op 36010000 cpu-ns/op 34241394 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 39258833 ns/op 39063667 cpu-ns/op 36019717 B/op 420472 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 74734104 ns/op 73265500 cpu-ns/op 50788564 B/op 907733 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 97163833 ns/op 93062000 cpu-ns/op 78853040 B/op 1038227 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 93125500 ns/op 90164000 cpu-ns/op 78915268 B/op 1040807 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 56 2001516 ns/op 1982500 cpu-ns/op 989248 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 73635938 ns/op 72405500 cpu-ns/op 43615528 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 40767375 ns/op 40116667 cpu-ns/op 23987317 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1125 92379 ns/op 75694 cpu-ns/op 1707 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 399 358064 ns/op 303486 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 50 2525853 ns/op 2431020 cpu-ns/op 133184 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 50408292 ns/op 45102000 cpu-ns/op 1329298 B/op 30020 allocs/op +BenchmarkMemoryInsert/N=10000 1 550634874 ns/op 524331000 cpu-ns/op 13281968 B/op 300030 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 15268 7936 ns/op 7934 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1561 75305 ns/op 59171 cpu-ns/op 3309 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1114 109331 ns/op 108956 cpu-ns/op 7420 B/op 175 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7830 15380 ns/op 15380 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 678 166644 ns/op 151117 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 280 427443 ns/op 407543 cpu-ns/op 24035 B/op 590 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1689 69562 ns/op 69487 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 90 1330911 ns/op 1146556 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 100 1089102 ns/op 1048630 cpu-ns/op 58137 B/op 1476 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 195 605668 ns/op 604523 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 11855079 ns/op 11650000 cpu-ns/op 1904827 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 32 3537220 ns/op 3465906 cpu-ns/op 73730 B/op 1528 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 16 6731969 ns/op 6733062 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 175005209 ns/op 171704000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 3 35974000 ns/op 35906000 cpu-ns/op 297789 B/op 1534 allocs/op +BenchmarkMemoryDenseRecall/N=1 1965 62863 ns/op 62832 cpu-ns/op 11352 B/op 209 allocs/op +BenchmarkMemoryDenseRecall/N=10 232 524951 ns/op 524129 cpu-ns/op 193357 B/op 4450 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 18343215 ns/op 18324333 cpu-ns/op 5687050 B/op 177376 allocs/op +PASS + +# Round 5; UTC 2026-10-03T11:33:31.341155+00:00; load (4.05517578125, 5.19189453125, 6.9423828125) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10232 ns/op 10217 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11227 ns/op 11220 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5497 22981 ns/op 22880 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7801 15788 ns/op 15779 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5282 23369 ns/op 23347 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 5785 19697 ns/op 19711 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 6308 19226 ns/op 19216 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5216 22765 ns/op 22756 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 19801 6081 ns/op 6074 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 27572 4285 ns/op 4264 cpu-ns/op 3904 B/op 57 allocs/op +BenchmarkMemoryRead/N=1/Diff 16171 7320 ns/op 7286 cpu-ns/op 5784 B/op 93 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1633 73404 ns/op 73389 cpu-ns/op 8609 B/op 192 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1567 80729 ns/op 80666 cpu-ns/op 11657 B/op 222 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2748 47398 ns/op 47346 cpu-ns/op 11512 B/op 216 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 10000 11319 ns/op 11310 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 10000 11352 ns/op 11346 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7359 16897 ns/op 16884 cpu-ns/op 2864 B/op 84 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10137 ns/op 10123 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4185 32756 ns/op 32681 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 2978 44811 ns/op 44736 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7826 15877 ns/op 15867 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5269 23462 ns/op 23455 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4759 25247 ns/op 25260 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5917 20329 ns/op 20331 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4645 25397 ns/op 25373 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14416 ns/op 14324 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 3085 38092 ns/op 37841 cpu-ns/op 35632 B/op 457 allocs/op +BenchmarkMemoryRead/N=10/Diff 1590 75322 ns/op 74999 cpu-ns/op 52434 B/op 739 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 382 321891 ns/op 317903 cpu-ns/op 90249 B/op 2012 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 336 340904 ns/op 339289 cpu-ns/op 118922 B/op 2179 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 246 480260 ns/op 474630 cpu-ns/op 140214 B/op 2722 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2187 66362 ns/op 59405 cpu-ns/op 13120 B/op 374 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 1701 76212 ns/op 75212 cpu-ns/op 41816 B/op 946 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2460 51390 ns/op 50854 cpu-ns/op 24024 B/op 769 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10334 ns/op 10318 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 468 262749 ns/op 260955 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 2661 49511 ns/op 49411 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 5770 20779 ns/op 20771 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 2919 45100 ns/op 45029 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 1216 97822 ns/op 97887 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1844 64012 ns/op 64044 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2054 58171 ns/op 58092 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1267 91942 ns/op 91131 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 326 359514 ns/op 357506 cpu-ns/op 343792 B/op 4237 allocs/op +BenchmarkMemoryRead/N=100/Diff 270 443937 ns/op 441889 cpu-ns/op 375774 B/op 4599 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 48 2540168 ns/op 2534604 cpu-ns/op 804732 B/op 16646 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 45 2919270 ns/op 2909867 cpu-ns/op 1136983 B/op 19756 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 40 3138888 ns/op 3127850 cpu-ns/op 1176536 B/op 20710 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1882 71598 ns/op 71451 cpu-ns/op 19904 B/op 377 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 174 688707 ns/op 686213 cpu-ns/op 431464 B/op 9592 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 333 369971 ns/op 367036 cpu-ns/op 232712 B/op 7441 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10301 ns/op 10299 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 54 2498346 ns/op 2487444 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 962 126700 ns/op 126753 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 1706 70706 ns/op 70709 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 1267 99858 ns/op 99803 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 123 959236 ns/op 959358 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 231 513142 ns/op 513113 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 310 387648 ns/op 387706 cpu-ns/op 1258 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 139 855274 ns/op 849209 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 37 3537948 ns/op 3523541 cpu-ns/op 3425394 B/op 42037 allocs/op +BenchmarkMemoryRead/N=1000/Diff 32 3807401 ns/op 3800188 cpu-ns/op 3631362 B/op 42407 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 13 8173869 ns/op 8157846 cpu-ns/op 5357852 B/op 97656 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 9 12886287 ns/op 12864444 cpu-ns/op 8434477 B/op 119209 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 13765472 ns/op 13515667 cpu-ns/op 8530378 B/op 121843 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 529 224162 ns/op 223319 cpu-ns/op 71744 B/op 380 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 15 6801650 ns/op 6776000 cpu-ns/op 4315144 B/op 95998 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 40 3381542 ns/op 3370675 cpu-ns/op 2417216 B/op 74060 allocs/op +BenchmarkMemoryRead/N=10000/ByID 12044 9924 ns/op 9922 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 4 28776104 ns/op 28181500 cpu-ns/op 15271920 B/op 480048 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 124 957295 ns/op 957605 cpu-ns/op 16290 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 201 593604 ns/op 593766 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 180 660749 ns/op 660633 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 8 16706776 ns/op 13524375 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 14 7967854 ns/op 6915286 cpu-ns/op 569 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 26 4106070 ns/op 4076500 cpu-ns/op 1278 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 10 10763033 ns/op 10652500 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 3 33787292 ns/op 33745333 cpu-ns/op 34241400 B/op 420037 allocs/op +BenchmarkMemoryRead/N=10000/Diff 3 35441625 ns/op 35429000 cpu-ns/op 36007365 B/op 420471 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 69748604 ns/op 69091000 cpu-ns/op 50788556 B/op 907733 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 123186938 ns/op 94086500 cpu-ns/op 78853040 B/op 1038227 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 93256916 ns/op 91750000 cpu-ns/op 78922032 B/op 1041042 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 66 1850886 ns/op 1850667 cpu-ns/op 989248 B/op 387 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 2 72971584 ns/op 72400000 cpu-ns/op 43615536 B/op 960022 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 3 42181917 ns/op 40305667 cpu-ns/op 23987317 B/op 740171 allocs/op +BenchmarkMemoryInsert/N=1 1137 90350 ns/op 74800 cpu-ns/op 1715 B/op 37 allocs/op +BenchmarkMemoryInsert/N=10 410 286399 ns/op 269268 cpu-ns/op 13657 B/op 307 allocs/op +BenchmarkMemoryInsert/N=100 52 2265752 ns/op 2237750 cpu-ns/op 133184 B/op 3007 allocs/op +BenchmarkMemoryInsert/N=1000 3 41658638 ns/op 41479667 cpu-ns/op 1329298 B/op 30020 allocs/op +BenchmarkMemoryInsert/N=10000 1 506502000 ns/op 505728000 cpu-ns/op 13281848 B/op 300029 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14941 7987 ns/op 7977 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1579 75573 ns/op 59286 cpu-ns/op 3363 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1149 107196 ns/op 107161 cpu-ns/op 7382 B/op 175 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7902 15617 ns/op 15558 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 687 164980 ns/op 149229 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 286 435433 ns/op 410636 cpu-ns/op 24043 B/op 590 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1758 68284 ns/op 68296 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 104 1139914 ns/op 1103346 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 109 1088235 ns/op 1058193 cpu-ns/op 58153 B/op 1477 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 200 604110 ns/op 603035 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12033167 ns/op 11849000 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 32 3491729 ns/op 3450875 cpu-ns/op 73708 B/op 1526 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 18 6384944 ns/op 6388222 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 172337500 ns/op 168345000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 3 36361097 ns/op 36233000 cpu-ns/op 297757 B/op 1534 allocs/op +BenchmarkMemoryDenseRecall/N=1 1958 64233 ns/op 64037 cpu-ns/op 11352 B/op 209 allocs/op +BenchmarkMemoryDenseRecall/N=10 204 580224 ns/op 568740 cpu-ns/op 193358 B/op 4450 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 18095465 ns/op 18076333 cpu-ns/op 5687053 B/op 177376 allocs/op +PASS diff --git a/docs/development/benchmarks/2026-10-03-memory-synced.txt b/docs/development/benchmarks/2026-10-03-memory-synced.txt new file mode 100644 index 00000000..4cfd0692 --- /dev/null +++ b/docs/development/benchmarks/2026-10-03-memory-synced.txt @@ -0,0 +1,581 @@ +# Memory performance after syncing master; 2026-10-03 +# Production commit: 9393edbe4bc29e4c7068dc672e4f52b85fbd4e2e +# Benchmark sources: a21d783b (identical performance*_test.go in both trees) +# Apple M4; darwin/arm64; Go 1.25.4; CPU includes user/system CPU and GC +# Five rounds, alternating version order; -test.cpu=1 -test.benchtime=100ms +# Wall time, cpu-ns/op, B/op and allocs/op; setup and cleanup excluded + +# Round 1; UTC 2026-10-03T11:31:33.486556+00:00; load (4.611328125, 5.7109375, 7.35693359375) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10387 ns/op 10308 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11565 ns/op 11519 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5815 23252 ns/op 22711 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 7263 16025 ns/op 15633 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5166 25030 ns/op 24364 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7104 16692 ns/op 16541 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7350 16340 ns/op 16273 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5440 22861 ns/op 22483 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18168 6622 ns/op 6612 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 33390 3597 ns/op 3573 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 18129 6526 ns/op 6443 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1663 74382 ns/op 74064 cpu-ns/op 7225 B/op 174 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1489 82826 ns/op 82351 cpu-ns/op 10137 B/op 201 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2778 48288 ns/op 47920 cpu-ns/op 9992 B/op 195 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9300 13943 ns/op 13844 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9594 13679 ns/op 13629 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7743 15156 ns/op 15170 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 2656 37979 ns/op 19759 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 1333 89409 ns/op 64455 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3076 50822 ns/op 48886 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 8434 15301 ns/op 15164 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5096 22923 ns/op 22899 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5102 23535 ns/op 23524 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5998 20810 ns/op 20811 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4803 24855 ns/op 24854 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14581 ns/op 14495 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4401 30628 ns/op 30448 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1860 64458 ns/op 64291 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 402 295846 ns/op 295400 cpu-ns/op 75351 B/op 1908 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 384 313496 ns/op 313198 cpu-ns/op 90168 B/op 2032 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 277 428283 ns/op 425069 cpu-ns/op 111460 B/op 2575 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2380 53686 ns/op 53642 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2414 51273 ns/op 51174 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2054 59338 ns/op 59339 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10595 ns/op 10576 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 546 215966 ns/op 215125 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3330 41571 ns/op 41406 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8625 14584 ns/op 14574 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3096 43453 ns/op 43380 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 5059 25175 ns/op 24398 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1938 62036 ns/op 61979 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2038 57978 ns/op 57892 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1212 92630 ns/op 91963 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 411 290062 ns/op 288710 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 327 571820 ns/op 403376 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 42 2760973 ns/op 2704690 cpu-ns/op 655849 B/op 15725 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 43 2695516 ns/op 2676395 cpu-ns/op 806681 B/op 17267 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 44 2768188 ns/op 2756364 cpu-ns/op 846242 B/op 18222 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2026 65801 ns/op 65485 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 280 433079 ns/op 429300 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2076 61696 ns/op 61428 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10680 ns/op 10630 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 67 2024499 ns/op 2020866 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3265 40677 ns/op 40622 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8397 14719 ns/op 14726 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3079 42535 ns/op 42503 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 4923 24013 ns/op 23875 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 243 502454 ns/op 499745 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 309 386289 ns/op 385958 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 142 830059 ns/op 824451 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2854577 ns/op 2847769 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 48 3591050 ns/op 3427583 cpu-ns/op 2181210 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 15 7310131 ns/op 7245267 cpu-ns/op 3934405 B/op 88635 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 10 10880458 ns/op 10775000 cpu-ns/op 5536636 B/op 104803 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 11297889 ns/op 11286333 cpu-ns/op 5636646 B/op 107437 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 847 144387 ns/op 144380 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 36 3927188 ns/op 3919528 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2115 59259 ns/op 59280 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10098 ns/op 10095 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 6 19795326 ns/op 19788833 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3210 39467 ns/op 39475 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8349 14444 ns/op 14445 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3058 41636 ns/op 41642 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4809 23554 ns/op 23559 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 21 5256974 ns/op 5260048 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 28 4060699 ns/op 4060179 cpu-ns/op 1284 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 12 9220337 ns/op 9212750 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 26417104 ns/op 26387250 cpu-ns/op 20161144 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 29811625 ns/op 29810500 cpu-ns/op 21405500 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 53522084 ns/op 53514000 cpu-ns/op 36619068 B/op 817704 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 66544230 ns/op 66531000 cpu-ns/op 49115088 B/op 906762 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 65805812 ns/op 65735000 cpu-ns/op 49184080 B/op 909577 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 117 1046515 ns/op 1045017 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 41487431 ns/op 41178667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2042 60193 ns/op 59910 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1300 131523 ns/op 95704 cpu-ns/op 1760 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 622 193512 ns/op 179450 cpu-ns/op 11912 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 91 1192541 ns/op 1170330 cpu-ns/op 113441 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 65216806 ns/op 42910000 cpu-ns/op 1129504 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 432895791 ns/op 430641000 cpu-ns/op 11282088 B/op 280033 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14055 8475 ns/op 8465 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1593 73525 ns/op 58573 cpu-ns/op 3327 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1423 86578 ns/op 86579 cpu-ns/op 6451 B/op 151 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7257 16001 ns/op 16002 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 663 166990 ns/op 151460 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 381 316412 ns/op 299228 cpu-ns/op 20881 B/op 515 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1780 68865 ns/op 68872 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 104 1142886 ns/op 1113279 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 127 877066 ns/op 648457 cpu-ns/op 51164 B/op 1366 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 201 592906 ns/op 593085 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12066847 ns/op 11837889 cpu-ns/op 1904825 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 134 881118 ns/op 846507 cpu-ns/op 52667 B/op 1415 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 16 6971292 ns/op 6973688 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 172621458 ns/op 168997000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 56 2054208 ns/op 1981429 cpu-ns/op 52687 B/op 1415 allocs/op +BenchmarkMemoryDenseRecall/N=1 2006 61477 ns/op 61430 cpu-ns/op 9944 B/op 193 allocs/op +BenchmarkMemoryDenseRecall/N=10 246 495266 ns/op 493829 cpu-ns/op 164683 B/op 4308 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 16830757 ns/op 16814667 cpu-ns/op 5356982 B/op 174893 allocs/op +PASS + +# Round 2; UTC 2026-10-03T11:31:50.299860+00:00; load (4.5546875, 5.64306640625, 7.3037109375) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10205 ns/op 10201 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11041 ns/op 11040 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5809 20879 ns/op 20887 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8840 14271 ns/op 14262 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5494 22673 ns/op 22657 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 6963 16423 ns/op 16307 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7470 15696 ns/op 15707 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5607 21620 ns/op 21622 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18628 6425 ns/op 6419 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 34836 3454 ns/op 3442 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19352 6151 ns/op 6134 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1718 71268 ns/op 71179 cpu-ns/op 7225 B/op 174 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1602 79764 ns/op 79800 cpu-ns/op 10137 B/op 201 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2869 45540 ns/op 45480 cpu-ns/op 9992 B/op 195 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9193 13295 ns/op 13288 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9848 13444 ns/op 13415 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 8007 15196 ns/op 15195 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10237 ns/op 10242 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4670 31517 ns/op 31223 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3235 42740 ns/op 42290 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 8587 14817 ns/op 14749 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5454 22606 ns/op 22590 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5175 23267 ns/op 23268 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5931 20250 ns/op 20269 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4858 24529 ns/op 24467 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14671 ns/op 14585 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4486 30363 ns/op 30247 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1879 64234 ns/op 64061 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 386 306721 ns/op 305246 cpu-ns/op 75351 B/op 1908 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 378 316604 ns/op 316238 cpu-ns/op 90168 B/op 2032 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 286 424076 ns/op 423472 cpu-ns/op 111461 B/op 2575 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2442 53561 ns/op 53498 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2263 55210 ns/op 54064 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2095 58297 ns/op 58267 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10376 ns/op 10307 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 561 214859 ns/op 214078 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3285 41630 ns/op 41405 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8391 14450 ns/op 14442 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3056 43008 ns/op 42887 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 5104 23493 ns/op 23492 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1956 61516 ns/op 61480 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2130 56577 ns/op 56589 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1249 90941 ns/op 90356 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 424 286062 ns/op 285090 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 326 366227 ns/op 364862 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 50 2463928 ns/op 2450100 cpu-ns/op 655843 B/op 15725 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 51 2516256 ns/op 2511804 cpu-ns/op 806681 B/op 17267 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 49 2681048 ns/op 2678796 cpu-ns/op 846241 B/op 18222 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2016 63743 ns/op 63755 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 284 417346 ns/op 416261 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2121 58198 ns/op 58197 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10638 ns/op 10617 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 62 2103622 ns/op 2095581 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3244 40704 ns/op 40619 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8472 14559 ns/op 14555 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3069 42601 ns/op 42552 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 5058 23678 ns/op 23689 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 244 486799 ns/op 486996 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 309 386703 ns/op 386819 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 142 831659 ns/op 826810 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2780910 ns/op 2772885 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 49 3008673 ns/op 3002020 cpu-ns/op 2181209 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6755721 ns/op 6738125 cpu-ns/op 3934408 B/op 88635 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 10 12202792 ns/op 11185300 cpu-ns/op 5536650 B/op 104803 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 11457778 ns/op 11452778 cpu-ns/op 5636550 B/op 107437 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 860 143688 ns/op 143669 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 34 4031168 ns/op 4016206 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2142 62498 ns/op 61544 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10081 ns/op 10082 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 6 20441451 ns/op 20428667 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3120 42700 ns/op 41998 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8310 15314 ns/op 15194 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3015 41608 ns/op 41611 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4618 24067 ns/op 24032 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 20 5235944 ns/op 5230500 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 27 3979026 ns/op 3979519 cpu-ns/op 1285 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 12 9298347 ns/op 9284250 cpu-ns/op 16547802 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 26996229 ns/op 26980500 cpu-ns/op 20161140 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 29111448 ns/op 29038000 cpu-ns/op 21405496 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 53383458 ns/op 52963500 cpu-ns/op 36618708 B/op 817703 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 65091916 ns/op 65015000 cpu-ns/op 49087256 B/op 906566 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 67226833 ns/op 67212000 cpu-ns/op 49183448 B/op 909575 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 116 991859 ns/op 991810 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 37716570 ns/op 37707667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2118 58177 ns/op 58109 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1123 92073 ns/op 76629 cpu-ns/op 1767 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 598 189249 ns/op 177540 cpu-ns/op 11913 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 98 1229928 ns/op 1204459 cpu-ns/op 113439 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 34619681 ns/op 34491333 cpu-ns/op 1129477 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 501580583 ns/op 468974000 cpu-ns/op 11282088 B/op 280033 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14550 8218 ns/op 8215 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1622 73206 ns/op 58296 cpu-ns/op 3310 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1426 89237 ns/op 88943 cpu-ns/op 6482 B/op 153 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7203 16345 ns/op 16164 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 578 174686 ns/op 156882 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 300 412770 ns/op 345267 cpu-ns/op 20886 B/op 516 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1708 69160 ns/op 69101 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 96 1314295 ns/op 1208198 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 82 1220868 ns/op 947061 cpu-ns/op 51184 B/op 1367 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 193 613147 ns/op 606409 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 30708829 ns/op 18532556 cpu-ns/op 1904827 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 108 1087512 ns/op 1010167 cpu-ns/op 52667 B/op 1415 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 14 7780554 ns/op 7488000 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 173588458 ns/op 169570000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 40 2763206 ns/op 2585700 cpu-ns/op 52725 B/op 1415 allocs/op +BenchmarkMemoryDenseRecall/N=1 1734 65393 ns/op 64719 cpu-ns/op 9944 B/op 193 allocs/op +BenchmarkMemoryDenseRecall/N=10 236 495213 ns/op 490936 cpu-ns/op 164684 B/op 4308 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 17027771 ns/op 17012000 cpu-ns/op 5356984 B/op 174893 allocs/op +PASS + +# Round 3; UTC 2026-10-03T11:32:40.652975+00:00; load (4.57763671875, 5.46875, 7.1416015625) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10806 ns/op 10646 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11303 ns/op 11262 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5700 21506 ns/op 21372 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8626 14410 ns/op 14402 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5278 23083 ns/op 23063 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7003 17524 ns/op 17109 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 5101 20101 ns/op 18861 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5492 22266 ns/op 22108 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18334 6490 ns/op 6480 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 35730 3415 ns/op 3382 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 18378 6461 ns/op 6414 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1638 73969 ns/op 73757 cpu-ns/op 7224 B/op 174 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1497 83621 ns/op 83329 cpu-ns/op 10137 B/op 201 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2724 48071 ns/op 47844 cpu-ns/op 9992 B/op 195 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 8877 15073 ns/op 13986 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9115 13829 ns/op 13798 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7705 16580 ns/op 16116 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 6340 21334 ns/op 15883 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 2362 60766 ns/op 41327 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3102 45861 ns/op 45248 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 7116 16623 ns/op 15867 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5043 24447 ns/op 23994 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5091 24979 ns/op 24891 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5755 22787 ns/op 22472 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4783 25687 ns/op 25632 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 9944 16575 ns/op 16386 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4423 34182 ns/op 33922 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1605 73337 ns/op 70923 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 316 342890 ns/op 334373 cpu-ns/op 75352 B/op 1908 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 310 361503 ns/op 357210 cpu-ns/op 90168 B/op 2032 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 270 467736 ns/op 465326 cpu-ns/op 111461 B/op 2575 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2269 56830 ns/op 56602 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2062 61146 ns/op 59419 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2043 65911 ns/op 65086 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10709 ns/op 10685 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 501 236733 ns/op 235305 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3135 44772 ns/op 44370 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8148 15614 ns/op 15541 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3048 45594 ns/op 45188 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 4992 24468 ns/op 24456 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1802 67018 ns/op 66187 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2082 58742 ns/op 58674 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1189 116739 ns/op 111327 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 386 319965 ns/op 314091 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 292 390680 ns/op 388336 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 48 2632886 ns/op 2619417 cpu-ns/op 655846 B/op 15725 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 43 2798775 ns/op 2776000 cpu-ns/op 806681 B/op 17267 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 45 2844042 ns/op 2839356 cpu-ns/op 846241 B/op 18222 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 1912 67293 ns/op 66826 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 242 485751 ns/op 470277 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2026 63264 ns/op 63075 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10877 ns/op 10843 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 56 2227807 ns/op 2216214 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3170 43782 ns/op 43412 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 7922 18851 ns/op 17217 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3033 47007 ns/op 46689 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 4819 24565 ns/op 24509 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 230 509385 ns/op 508839 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 304 400294 ns/op 399188 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 141 838323 ns/op 833411 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2776216 ns/op 2769981 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 49 2997249 ns/op 2989673 cpu-ns/op 2181206 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 16 6888326 ns/op 6875062 cpu-ns/op 3934408 B/op 88635 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 10 11361583 ns/op 11323100 cpu-ns/op 5536650 B/op 104803 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 12316301 ns/op 12129556 cpu-ns/op 5636550 B/op 107437 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 858 143411 ns/op 143429 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 34 3970156 ns/op 3955647 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2061 59704 ns/op 59688 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10846 ns/op 10617 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 6 19988458 ns/op 19980833 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3202 39854 ns/op 39835 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8382 14548 ns/op 14550 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3037 42190 ns/op 42151 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 5044 23283 ns/op 23291 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 21 5172833 ns/op 5172524 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 27 3980569 ns/op 3981519 cpu-ns/op 1285 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 10 10568200 ns/op 10552600 cpu-ns/op 16547801 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 28296562 ns/op 28136500 cpu-ns/op 20161140 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 28981552 ns/op 28916000 cpu-ns/op 21405496 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 51088875 ns/op 51110000 cpu-ns/op 36619068 B/op 817704 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 66408229 ns/op 66407000 cpu-ns/op 49095988 B/op 906758 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 67214208 ns/op 67160500 cpu-ns/op 49184080 B/op 909577 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 122 957640 ns/op 957951 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 40928430 ns/op 40929667 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2022 59500 ns/op 59482 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1126 90869 ns/op 75200 cpu-ns/op 1768 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 594 182530 ns/op 167210 cpu-ns/op 11958 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 94 1206417 ns/op 1185266 cpu-ns/op 113439 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 33808986 ns/op 33548000 cpu-ns/op 1129541 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 429479000 ns/op 424304000 cpu-ns/op 11282104 B/op 280034 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14215 8476 ns/op 8480 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1563 74395 ns/op 59354 cpu-ns/op 3336 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1414 87410 ns/op 87435 cpu-ns/op 6429 B/op 151 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7519 17623 ns/op 17297 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 613 187466 ns/op 168307 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 278 368759 ns/op 337687 cpu-ns/op 20865 B/op 514 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1728 71393 ns/op 70952 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 92 1147667 ns/op 1109500 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 148 781135 ns/op 696439 cpu-ns/op 51190 B/op 1368 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 194 613625 ns/op 611526 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12278417 ns/op 11892444 cpu-ns/op 1904827 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 123 1022636 ns/op 893984 cpu-ns/op 52652 B/op 1414 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 14 7313857 ns/op 7158286 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 253379542 ns/op 215893000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 36 2967588 ns/op 2724056 cpu-ns/op 52728 B/op 1415 allocs/op +BenchmarkMemoryDenseRecall/N=1 1714 65390 ns/op 65125 cpu-ns/op 9944 B/op 193 allocs/op +BenchmarkMemoryDenseRecall/N=10 234 511097 ns/op 509944 cpu-ns/op 164684 B/op 4308 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 17002597 ns/op 16866167 cpu-ns/op 5350685 B/op 174892 allocs/op +PASS + +# Round 4; UTC 2026-10-03T11:32:57.202703+00:00; load (4.69140625, 5.4375, 7.0908203125) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10384 ns/op 10349 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11135 ns/op 11125 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5696 21489 ns/op 21450 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8770 14359 ns/op 14345 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5310 22661 ns/op 22614 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 6964 16343 ns/op 16342 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 6906 16361 ns/op 16329 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5434 21779 ns/op 21662 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18354 6510 ns/op 6498 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 35151 3448 ns/op 3434 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19047 6251 ns/op 6229 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1647 72027 ns/op 72031 cpu-ns/op 7224 B/op 174 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1593 79599 ns/op 79558 cpu-ns/op 10137 B/op 201 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2844 45416 ns/op 45361 cpu-ns/op 9992 B/op 195 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9699 13175 ns/op 13161 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9588 13854 ns/op 13826 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7843 14940 ns/op 14941 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10217 ns/op 10196 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4590 30037 ns/op 29937 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3356 40421 ns/op 40297 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 8649 14271 ns/op 14257 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5582 22496 ns/op 22478 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 5102 24815 ns/op 24171 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 5901 20795 ns/op 20611 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4936 24242 ns/op 24245 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 7942 14703 ns/op 14607 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4466 30250 ns/op 30133 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1875 63536 ns/op 63368 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 404 293817 ns/op 293480 cpu-ns/op 75352 B/op 1908 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 384 316423 ns/op 315958 cpu-ns/op 90167 B/op 2032 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 283 420592 ns/op 420028 cpu-ns/op 111461 B/op 2575 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2436 53224 ns/op 53167 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2341 75505 ns/op 59979 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2186 67201 ns/op 65339 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10856 10887 ns/op 10786 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 549 222602 ns/op 221089 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3260 41321 ns/op 40983 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 7557 14618 ns/op 14627 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3158 42322 ns/op 42238 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 5124 23617 ns/op 23605 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1941 61526 ns/op 61504 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2056 57541 ns/op 57282 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1261 93387 ns/op 92593 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 415 291216 ns/op 290092 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 322 368996 ns/op 367851 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 50 2410272 ns/op 2405500 cpu-ns/op 655843 B/op 15725 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 50 2558999 ns/op 2554960 cpu-ns/op 806683 B/op 17267 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 49 2692493 ns/op 2687041 cpu-ns/op 846241 B/op 18222 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2042 62845 ns/op 62767 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 285 414193 ns/op 413032 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2142 58734 ns/op 58722 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10272 ns/op 10270 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 70 2005728 ns/op 2000086 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3265 40700 ns/op 40636 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8458 14538 ns/op 14532 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3213 42597 ns/op 42451 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 4358 25157 ns/op 24484 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 234 500027 ns/op 497949 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 314 382032 ns/op 381946 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 145 824641 ns/op 819579 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 52 2839574 ns/op 2823231 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 49 3056773 ns/op 3046102 cpu-ns/op 2181208 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 15 7131700 ns/op 7057000 cpu-ns/op 3934405 B/op 88635 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 10 11212500 ns/op 11122500 cpu-ns/op 5536650 B/op 104803 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 12553236 ns/op 12213556 cpu-ns/op 5636550 B/op 107437 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 840 146362 ns/op 145179 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 34 4059811 ns/op 4032471 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 2085 59388 ns/op 59432 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10392 ns/op 10291 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 5 21101575 ns/op 21088200 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3198 39828 ns/op 39827 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 8431 14386 ns/op 14385 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3084 41532 ns/op 41476 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4918 23388 ns/op 23389 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 21 5184306 ns/op 5187048 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 27 8588718 ns/op 6502481 cpu-ns/op 1285 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 10 10117425 ns/op 10105100 cpu-ns/op 16547806 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 26515229 ns/op 26509750 cpu-ns/op 20161140 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 28629573 ns/op 28630750 cpu-ns/op 21405496 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 55009292 ns/op 54989000 cpu-ns/op 36619068 B/op 817704 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 69272916 ns/op 68087500 cpu-ns/op 49095988 B/op 906758 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 77652125 ns/op 71122500 cpu-ns/op 49184080 B/op 909577 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 120 967376 ns/op 967583 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 42047292 ns/op 42057000 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2059 59148 ns/op 59126 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1155 98989 ns/op 80980 cpu-ns/op 1770 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 588 189115 ns/op 175491 cpu-ns/op 11913 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 94 1193859 ns/op 1167851 cpu-ns/op 113439 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 34271805 ns/op 34121000 cpu-ns/op 1129509 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 439256709 ns/op 434464000 cpu-ns/op 11282104 B/op 280034 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 13594 8785 ns/op 8737 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1618 73980 ns/op 59057 cpu-ns/op 3340 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1437 85876 ns/op 85867 cpu-ns/op 6430 B/op 151 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7586 15913 ns/op 15903 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 674 166303 ns/op 151263 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 380 317576 ns/op 299808 cpu-ns/op 20867 B/op 515 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1748 68880 ns/op 68889 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 100 1389737 ns/op 1113750 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 158 735501 ns/op 670671 cpu-ns/op 51192 B/op 1368 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 201 596544 ns/op 596318 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12586018 ns/op 12312667 cpu-ns/op 1904827 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 132 891211 ns/op 856697 cpu-ns/op 52673 B/op 1415 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 16 6858831 ns/op 6852875 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 179143958 ns/op 174812000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 40 2565351 ns/op 2308450 cpu-ns/op 52754 B/op 1415 allocs/op +BenchmarkMemoryDenseRecall/N=1 2000 63486 ns/op 63309 cpu-ns/op 9944 B/op 193 allocs/op +BenchmarkMemoryDenseRecall/N=10 237 502905 ns/op 501848 cpu-ns/op 164684 B/op 4308 allocs/op +BenchmarkMemoryDenseRecall/N=100 6 16960188 ns/op 16932000 cpu-ns/op 5356982 B/op 174893 allocs/op +PASS + +# Round 5; UTC 2026-10-03T11:33:48.208844+00:00; load (4.06298828125, 5.11474609375, 6.873046875) +goos: darwin +goarch: arm64 +pkg: github.com/mnemon-dev/mnemon/internal/memory +cpu: Apple M4 +BenchmarkMemoryRead/N=1/ByID 10000 10299 ns/op 10196 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/AllActive 10000 11276 ns/op 11192 cpu-ns/op 2296 B/op 69 allocs/op +BenchmarkMemoryRead/N=1/Ranked 5846 21249 ns/op 21231 cpu-ns/op 2584 B/op 73 allocs/op +BenchmarkMemoryRead/N=1/SourceLatest 8506 14481 ns/op 14449 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/SourceRecent 5372 22612 ns/op 22614 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=1/Entity 7215 16557 ns/op 16478 cpu-ns/op 632 B/op 20 allocs/op +BenchmarkMemoryRead/N=1/EntityMiss 7225 16059 ns/op 16060 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1/RankedKeywordMiss 5593 21360 ns/op 21357 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=1/Embeddings 18678 6462 ns/op 6460 cpu-ns/op 1888 B/op 24 allocs/op +BenchmarkMemoryRead/N=1/Keyword 34941 3535 ns/op 3501 cpu-ns/op 2240 B/op 46 allocs/op +BenchmarkMemoryRead/N=1/Diff 19284 6206 ns/op 6147 cpu-ns/op 3224 B/op 77 allocs/op +BenchmarkMemoryRead/N=1/RecallKeyword 1669 72187 ns/op 72143 cpu-ns/op 7224 B/op 174 allocs/op +BenchmarkMemoryRead/N=1/RecallHybrid 1579 80029 ns/op 79989 cpu-ns/op 10137 B/op 201 allocs/op +BenchmarkMemoryRead/N=1/RecallWhy 2853 45962 ns/op 45914 cpu-ns/op 9992 B/op 195 allocs/op +BenchmarkMemoryRead/N=1/SemanticEmbedding 9235 13396 ns/op 13357 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/SemanticTokens 9642 13895 ns/op 13786 cpu-ns/op 3040 B/op 90 allocs/op +BenchmarkMemoryRead/N=1/Neighborhood 7843 14984 ns/op 14986 cpu-ns/op 1296 B/op 26 allocs/op +BenchmarkMemoryRead/N=10/ByID 10000 10442 ns/op 10413 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10/AllActive 4598 30271 ns/op 30172 cpu-ns/op 16000 B/op 505 allocs/op +BenchmarkMemoryRead/N=10/Ranked 3355 41020 ns/op 40953 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10/SourceLatest 6950 14749 ns/op 14735 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/SourceRecent 5343 22985 ns/op 22964 cpu-ns/op 2504 B/op 74 allocs/op +BenchmarkMemoryRead/N=10/Entity 4953 23506 ns/op 23503 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10/EntityMiss 6014 20190 ns/op 20195 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10/RankedKeywordMiss 4664 24532 ns/op 24526 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=10/Embeddings 10000 14671 ns/op 14588 cpu-ns/op 16200 B/op 127 allocs/op +BenchmarkMemoryRead/N=10/Keyword 4560 30198 ns/op 30084 cpu-ns/op 21296 B/op 365 allocs/op +BenchmarkMemoryRead/N=10/Diff 1880 64217 ns/op 64047 cpu-ns/op 30929 B/op 607 allocs/op +BenchmarkMemoryRead/N=10/RecallKeyword 396 304153 ns/op 302755 cpu-ns/op 75351 B/op 1908 allocs/op +BenchmarkMemoryRead/N=10/RecallHybrid 320 365245 ns/op 346831 cpu-ns/op 90168 B/op 2032 allocs/op +BenchmarkMemoryRead/N=10/RecallWhy 277 426146 ns/op 423036 cpu-ns/op 111460 B/op 2575 allocs/op +BenchmarkMemoryRead/N=10/SemanticEmbedding 2450 53288 ns/op 53227 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10/SemanticTokens 2290 51829 ns/op 51678 cpu-ns/op 24088 B/op 723 allocs/op +BenchmarkMemoryRead/N=10/Neighborhood 2089 58915 ns/op 58887 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=100/ByID 10000 10207 ns/op 10192 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=100/AllActive 555 217625 ns/op 216647 cpu-ns/op 152560 B/op 4828 allocs/op +BenchmarkMemoryRead/N=100/Ranked 3301 41766 ns/op 41648 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=100/SourceLatest 8414 14693 ns/op 14677 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=100/SourceRecent 3141 42421 ns/op 42380 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=100/Entity 5193 23272 ns/op 23278 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=100/EntityMiss 1942 61648 ns/op 61668 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=100/RankedKeywordMiss 2152 56370 ns/op 56373 cpu-ns/op 1256 B/op 29 allocs/op +BenchmarkMemoryRead/N=100/Embeddings 1275 91279 ns/op 90494 cpu-ns/op 155576 B/op 1120 allocs/op +BenchmarkMemoryRead/N=100/Keyword 434 282460 ns/op 281435 cpu-ns/op 202736 B/op 3335 allocs/op +BenchmarkMemoryRead/N=100/Diff 332 365696 ns/op 364669 cpu-ns/op 222680 B/op 3644 allocs/op +BenchmarkMemoryRead/N=100/RecallKeyword 50 2419492 ns/op 2415540 cpu-ns/op 655843 B/op 15725 allocs/op +BenchmarkMemoryRead/N=100/RecallHybrid 50 2558901 ns/op 2555020 cpu-ns/op 806683 B/op 17267 allocs/op +BenchmarkMemoryRead/N=100/RecallWhy 49 2678935 ns/op 2675571 cpu-ns/op 846241 B/op 18222 allocs/op +BenchmarkMemoryRead/N=100/SemanticEmbedding 2018 64349 ns/op 63991 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=100/SemanticTokens 290 417229 ns/op 416055 cpu-ns/op 227608 B/op 6936 allocs/op +BenchmarkMemoryRead/N=100/Neighborhood 2061 59347 ns/op 59280 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=1000/ByID 10000 10873 ns/op 10823 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=1000/AllActive 58 2120884 ns/op 2109655 cpu-ns/op 1514320 B/op 48031 allocs/op +BenchmarkMemoryRead/N=1000/Ranked 3310 40546 ns/op 40474 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=1000/SourceLatest 8475 14610 ns/op 14604 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=1000/SourceRecent 3156 42264 ns/op 42153 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=1000/Entity 4968 24166 ns/op 23985 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=1000/EntityMiss 244 486872 ns/op 487066 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=1000/RankedKeywordMiss 310 382551 ns/op 382597 cpu-ns/op 1257 B/op 29 allocs/op +BenchmarkMemoryRead/N=1000/Embeddings 142 839658 ns/op 833549 cpu-ns/op 1512473 B/op 11023 allocs/op +BenchmarkMemoryRead/N=1000/Keyword 49 2842065 ns/op 2839490 cpu-ns/op 2017137 B/op 33035 allocs/op +BenchmarkMemoryRead/N=1000/Diff 49 3111613 ns/op 3102388 cpu-ns/op 2181209 B/op 33348 allocs/op +BenchmarkMemoryRead/N=1000/RecallKeyword 15 7252364 ns/op 7206667 cpu-ns/op 3934405 B/op 88635 allocs/op +BenchmarkMemoryRead/N=1000/RecallHybrid 10 10420733 ns/op 10371400 cpu-ns/op 5536729 B/op 104803 allocs/op +BenchmarkMemoryRead/N=1000/RecallWhy 9 11235903 ns/op 11229000 cpu-ns/op 5636535 B/op 107437 allocs/op +BenchmarkMemoryRead/N=1000/SemanticEmbedding 860 145015 ns/op 145035 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=1000/SemanticTokens 36 3964293 ns/op 3956111 cpu-ns/op 2258968 B/op 69039 allocs/op +BenchmarkMemoryRead/N=1000/Neighborhood 1938 59914 ns/op 59833 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryRead/N=10000/ByID 10000 10040 ns/op 10036 cpu-ns/op 2392 B/op 73 allocs/op +BenchmarkMemoryRead/N=10000/AllActive 6 20914215 ns/op 20885333 cpu-ns/op 15271184 B/op 480038 allocs/op +BenchmarkMemoryRead/N=10000/Ranked 3052 40845 ns/op 40722 cpu-ns/op 16288 B/op 509 allocs/op +BenchmarkMemoryRead/N=10000/SourceLatest 7956 14595 ns/op 14588 cpu-ns/op 2456 B/op 74 allocs/op +BenchmarkMemoryRead/N=10000/SourceRecent 3042 41091 ns/op 41116 cpu-ns/op 16208 B/op 510 allocs/op +BenchmarkMemoryRead/N=10000/Entity 4863 23504 ns/op 23506 cpu-ns/op 1544 B/op 60 allocs/op +BenchmarkMemoryRead/N=10000/EntityMiss 20 5252902 ns/op 5256650 cpu-ns/op 568 B/op 15 allocs/op +BenchmarkMemoryRead/N=10000/RankedKeywordMiss 27 3987424 ns/op 3990111 cpu-ns/op 1285 B/op 29 allocs/op +BenchmarkMemoryRead/N=10000/Embeddings 12 9245715 ns/op 9218333 cpu-ns/op 16547804 B/op 110031 allocs/op +BenchmarkMemoryRead/N=10000/Keyword 4 26492073 ns/op 26474000 cpu-ns/op 20161144 B/op 330035 allocs/op +BenchmarkMemoryRead/N=10000/Diff 4 29573635 ns/op 29571500 cpu-ns/op 21405496 B/op 330406 allocs/op +BenchmarkMemoryRead/N=10000/RecallKeyword 2 53617250 ns/op 53595000 cpu-ns/op 36619068 B/op 817704 allocs/op +BenchmarkMemoryRead/N=10000/RecallHybrid 2 67587146 ns/op 67569500 cpu-ns/op 49087792 B/op 906567 allocs/op +BenchmarkMemoryRead/N=10000/RecallWhy 2 65878292 ns/op 65881000 cpu-ns/op 49184080 B/op 909577 allocs/op +BenchmarkMemoryRead/N=10000/SemanticEmbedding 118 988328 ns/op 989025 cpu-ns/op 12736 B/op 373 allocs/op +BenchmarkMemoryRead/N=10000/SemanticTokens 3 41333278 ns/op 41311333 cpu-ns/op 22711832 B/op 690046 allocs/op +BenchmarkMemoryRead/N=10000/Neighborhood 2004 59487 ns/op 59468 cpu-ns/op 9504 B/op 276 allocs/op +BenchmarkMemoryInsert/N=1 1136 91669 ns/op 75195 cpu-ns/op 1795 B/op 40 allocs/op +BenchmarkMemoryInsert/N=10 614 197439 ns/op 179936 cpu-ns/op 11912 B/op 292 allocs/op +BenchmarkMemoryInsert/N=100 96 1237622 ns/op 1204521 cpu-ns/op 113437 B/op 2812 allocs/op +BenchmarkMemoryInsert/N=1000 3 34850027 ns/op 34603000 cpu-ns/op 1129509 B/op 28024 allocs/op +BenchmarkMemoryInsert/N=10000 1 432977208 ns/op 431604000 cpu-ns/op 11282104 B/op 280034 allocs/op +BenchmarkMemoryMaintenance/N=1/KnownEntities 14294 8309 ns/op 8302 cpu-ns/op 696 B/op 18 allocs/op +BenchmarkMemoryMaintenance/N=1/Retention 1528 75479 ns/op 59342 cpu-ns/op 3340 B/op 98 allocs/op +BenchmarkMemoryMaintenance/N=1/EngineProvided 1432 87616 ns/op 87622 cpu-ns/op 6453 B/op 153 allocs/op +BenchmarkMemoryMaintenance/N=10/KnownEntities 7126 16028 ns/op 16022 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10/Retention 673 166960 ns/op 151184 cpu-ns/op 20616 B/op 677 allocs/op +BenchmarkMemoryMaintenance/N=10/EngineProvided 364 326794 ns/op 304670 cpu-ns/op 20858 B/op 514 allocs/op +BenchmarkMemoryMaintenance/N=100/KnownEntities 1778 70153 ns/op 69879 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=100/Retention 104 1146936 ns/op 1113288 cpu-ns/op 192584 B/op 6272 allocs/op +BenchmarkMemoryMaintenance/N=100/EngineProvided 178 664884 ns/op 643747 cpu-ns/op 51164 B/op 1366 allocs/op +BenchmarkMemoryMaintenance/N=1000/KnownEntities 199 600935 ns/op 599879 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=1000/Retention 9 12130255 ns/op 11916556 cpu-ns/op 1904827 B/op 62092 allocs/op +BenchmarkMemoryMaintenance/N=1000/EngineProvided 136 863309 ns/op 830015 cpu-ns/op 52653 B/op 1414 allocs/op +BenchmarkMemoryMaintenance/N=10000/KnownEntities 18 6530120 ns/op 6531056 cpu-ns/op 1584 B/op 48 allocs/op +BenchmarkMemoryMaintenance/N=10000/Retention 1 176413333 ns/op 171657000 cpu-ns/op 20506536 B/op 620173 allocs/op +BenchmarkMemoryMaintenance/N=10000/EngineProvided 52 2232851 ns/op 2154673 cpu-ns/op 52725 B/op 1416 allocs/op +BenchmarkMemoryDenseRecall/N=1 2004 62185 ns/op 62119 cpu-ns/op 9944 B/op 193 allocs/op +BenchmarkMemoryDenseRecall/N=10 244 491229 ns/op 490668 cpu-ns/op 164683 B/op 4308 allocs/op +BenchmarkMemoryDenseRecall/N=100 7 16842054 ns/op 16830429 cpu-ns/op 5349785 B/op 174892 allocs/op +PASS diff --git a/docs/development/memory-algorithm-performance.md b/docs/development/memory-algorithm-performance.md index fdf81dee..febb9a2a 100644 --- a/docs/development/memory-algorithm-performance.md +++ b/docs/development/memory-algorithm-performance.md @@ -1,10 +1,181 @@ # Memory algorithm performance audit -Date: 2026-10-03. Production baseline: `4d312c4e`. Optimized implementation: -`766c3965`. Work was isolated in `codex/memory-algorithm-performance`. +Updated: 2026-10-03. Current baseline: default branch `master` at `5c98ff9c`. +Current optimized implementation: `9393edbe`, after merging that baseline in +`6d1511ac`. Work remains isolated in `codex/memory-algorithm-performance`. [中文报告](../zh/development/memory-algorithm-performance.md) +## Revalidation against the latest master + +The default branch is named `master`. It now includes PR #148: covering edge +indexes, scoped supersedes reads, a caller-loaded active-insight snapshot, +per-recall ranked-transition caching, embedding keep-alive, mmap and database +compaction. Those changes are retained. They are part of the **new baseline**, +not attributed to this PR's incremental gains. The historical audit below +preserves the earlier measurements separately. + +The merge preserves upstream's correctness rule: rank each complete neighborhood +by intent-weighted structure plus cosine similarity **before** applying the visit +budget. Transition ties still use insight ID and edge type. The request-local +cache now retains those ranked transitions and reuses precomputed scalar cosine +scores instead of recalculating cosine for each edge. Query and intent are fixed +for the lifetime of that cache. + +An additional change reuses the vector decode buffer within a synchronous +embedding scan. `DeserializeVector` and `DeserializeVectorInto` share one float32 +decoder; callers that need an owned vector still get one. Recall consumes each +vector's score before the next row overwrites the buffer. The stored format, +arithmetic order, invalid-blob behavior and query lifetime are unchanged. + +Against current master, both versions already make at most U successful +neighborhood reads for U distinct expanded nodes. Let E_U be the total incident +edges loaded, C the reranked candidates, and d the vector dimension. The cosine +component changes from `O((N + E_U + C)d)` to `O(Nd + E_U + C)`. Both versions +retain `O(sum(deg(v) log deg(v)))` neighborhood sorting before traversal, as +required by the upstream budget rule. Dense neighborhoods therefore remain +expensive; a visit budget does not bound the size of the adjacency lists read. + +For fixed dimension d, buffer reuse reduces cumulative temporary decoded-vector +allocation from `O(Nd)` to `O(d)` per recall. With mixed dimensions it allocates +only when a larger capacity is needed. This is an allocation improvement; +exact vector comparison remains `O(Nd)`, scalar caches remain `O(N)`, and the +reported B/op values are cumulative allocation, not peak resident memory. The +ordered-read indexes, local BFS, semantic top-K and transaction statement reuse +retain the bounds described in the historical audit. + +### Fresh measurements + +The fixture and methodology below are unchanged: N=1/10/100/1,000/10,000, +128-dimensional vectors, real temporary SQLite WAL stores, Apple M4, +Go 1.25.4, one P, five alternating rounds at 100 ms per case. The final dataset +contains **108 cases × 5 rounds × 2 versions = 1,080 samples**. It compares +`5c98ff9c` directly with `9393edbe`; intermediate merge-only results are excluded. +No other local test suite ran concurrently with these measurements. + +CPU **µs/op**, current master → final PR, median of five runs: + +| Path | N=1 | N=10 | N=100 | +|---|---:|---:|---:| +| ByID | 10.3 → 10.3 | 10.3 → 10.4 | 10.4 → 10.6 | +| AllActive | 11.3 → 11.2 | 33.2 → 31.2 | 262.4 → 216.6 | +| Ranked | 22.9 → 21.4 | 45.6 → 42.3 | 50.1 → 41.4 | +| SourceLatest | 15.9 → 14.4 | 15.9 → 14.7 | 21.0 → 14.6 | +| SourceRecent | 23.6 → 22.7 | 24.0 → 22.9 | 45.8 → 42.9 | +| Entity | 19.7 → 16.5 | 25.6 → 23.5 | 98.0 → 23.6 | +| EntityMiss | 19.2 → 16.3 | 20.8 → 20.6 | 64.4 → 61.7 | +| RankedKeywordMiss | 22.7 → 21.7 | 25.6 → 24.5 | 57.9 → 57.3 | +| Embeddings | 6.1 → 6.5 | 14.3 → 14.6 | 91.1 → 92.0 | +| Keyword | 4.3 → 3.4 | 37.8 → 30.2 | 361.6 → 288.7 | +| Diff | 7.3 → 6.2 | 75.4 → 64.1 | 470.5 → 367.9 | +| RecallKeyword | 74.4 → 72.1 | 318.3 → 302.8 | 2,699.5 → 2,450.1 | +| RecallHybrid | 82.2 → 80.0 | 339.3 → 316.2 | 3,037.5 → 2,555.0 | +| RecallWhy | 47.7 → 45.9 | 453.9 → 423.5 | 3,236.2 → 2,687.0 | +| SemanticEmbedding | 11.6 → 13.4 | 54.0 → 53.5 | 70.6 → 64.0 | +| SemanticTokens | 11.7 → 13.8 | 75.1 → 54.1 | 691.6 → 416.3 | +| Neighborhood | 17.4 → 15.2 | 50.1 → 59.3 | 368.4 → 59.3 | +| AtomicInsert | 75.7 → 76.6 | 278.9 → 177.5 | 2,291.2 → 1,185.3 | +| KnownEntities | 8.0 → 8.5 | 15.8 → 16.0 | 69.5 → 69.1 | +| Retention | 59.3 → 59.1 | 153.5 → 151.5 | 1,107.3 → 1,113.3 | +| EngineProvided | 109.6 → 87.4 | 410.6 → 304.7 | 1,048.6 → 670.7 | + +At N=10,000, CPU **ms/op** (lower is better; ratio is master/final): + +| Path | CPU ms master → PR | CPU ratio | Allocation KiB master → PR | +|---|---:|---:|---:| +| ByID | 0.0100 → 0.0101 | 0.99× | 2.3 → 2.3 | +| AllActive | 29.2625 → 20.4287 | 1.43× | 14,914.0 → 14,913.3 | +| Ranked | 0.9576 → 0.0398 | 24.04× | 15.9 → 15.9 | +| SourceLatest | 0.6016 → 0.0146 | 41.35× | 2.4 → 2.4 | +| SourceRecent | 0.6606 → 0.0416 | 15.88× | 15.8 → 15.8 | +| Entity | 13.4870 → 0.0235 | 573.77× | 1.5 → 1.5 | +| EntityMiss | 5.5477 → 5.2305 | 1.06× | 0.6 → 0.6 | +| RankedKeywordMiss | 4.0758 → 3.9901 | 1.02× | 1.2 → 1.3 | +| Embeddings | 10.4085 → 9.2843 | 1.12× | 16,160.0 → 16,160.0 | +| Keyword | 33.7453 → 26.5098 | 1.27× | 33,438.9 → 19,688.6 | +| Diff | 36.3317 → 29.0380 | 1.25× | 35,175.5 → 20,903.8 | +| RecallKeyword | 69.9800 → 53.5140 | 1.31× | 49,598.2 → 35,760.8 | +| RecallHybrid | 93.0620 → 66.5310 | 1.40× | 77,004.9 → 47,945.3 | +| RecallWhy | 91.0855 → 67.1605 | 1.36× | 77,072.3 → 48,031.3 | +| SemanticEmbedding | 1.8507 → 0.9890 | 1.87× | 966.1 → 12.4 | +| SemanticTokens | 72.4055 → 41.1787 | 1.76× | 42,593.3 → 22,179.5 | +| Neighborhood | 40.3057 → 0.0595 | 677.77× | 23,425.1 → 9.3 | +| AtomicInsert | 524.3310 → 431.6040 | 1.21× | 12,970.6 → 11,017.7 | +| KnownEntities | 6.7086 → 6.9737 | 0.96× | 1.5 → 1.5 | +| Retention | 170.1040 → 171.6570 | 0.99× | 20,025.9 → 20,025.9 | +| EngineProvided | 37.8323 → 2.3085 | 16.39× | 290.8 → 51.5 | + +Dense graph, CPU ms/op and cumulative allocation KiB/op: + +| N | CPU ms master → PR | CPU ratio | Allocation KiB master → PR | +|---|---:|---:|---:| +| 1 | 0.0640 → 0.0633 | 1.01× | 11.1 → 9.7 | +| 10 | 0.5254 → 0.4938 | 1.06× | 188.8 → 160.8 | +| 100 | 18.3243 → 16.8662 | 1.09× | 5,553.8 → 5,231.4 | + +At N=10,000, hybrid recall allocation fell from 78.85 MB to +49.10 MB per operation (37.7% less). Dense recall at N=100 improves +1.09× over current master. The earlier 6.51× figure used a baseline without +master's transition cache and covering indexes and does not describe this delta. + +Small inputs retain fixed-cost tradeoffs: N=10 neighborhood reads take +59.34 µs versus 50.09 µs; N=1 semantic embedding/token paths take 13.36/13.79 µs +versus 11.57/11.75 µs. Known-entity scanning at N=10,000 takes 6.974 ms versus +6.709 ms (about 4% more); retention is near neutral (170.104 → 171.657 ms). +Unmodified embedding loading also varies (10.409 → 9.284 ms), so small timing +ratios should not be interpreted as algorithm changes. ID lookup is near neutral. +The Entity benchmark's large gain is fixture-specific: every record has the entity, so the +indexed read can stop after ten matches. An absent JSON entity or substring +still requires a linear scan. These shared-host timings are observations, not +cold-start or production latency guarantees. + +The isolated decode-buffer probe compared the merge commit `6d1511ac` with +`9393edbe`: three alternating rounds, N=10,000, hybrid/WHY recall, 200 ms per +case. Hybrid allocation fell from approximately 59.35 MB to 49.11 MB per call, +about 17%, matching the eliminated 9,999 temporary 128-element float64 buffers. +This probe is separate from the full master-versus-final dataset. + +All final samples are saved as [current master](benchmarks/2026-10-03-memory-main.txt) +and [final PR](benchmarks/2026-10-03-memory-synced.txt). The isolated allocation +probe is saved as [decode before](benchmarks/2026-10-03-memory-decode-before.txt) +and [decode after](benchmarks/2026-10-03-memory-decode-after.txt). + +### Compatibility and validation after the merge + +- `go build -o mnemon .`, `make test`, and + `go test -race ./internal/memory/... ./cmd/memory -count=1` passed on the final + production implementation. +- `MNEMON_EMBED_ENDPOINT=http://127.0.0.1:1 bash scripts/e2e_test.sh`: all + **258 assertions passed** after the buffer change. +- `npm test --prefix npm/cli`: **13 passed**. The imported OpenCode runtime suite + and ZCode shell hooks passed locally. The Windows PowerShell hook probe was + skipped on this macOS host; it belongs to the manual Windows integration suite. +- The independent full-vector traversal oracle is now copied from `5c98ff9c`. + Cached scores and via labels match for all four intents, three traversal + budgets, repeated/overlapping anchors, ties, cycles, deleted nodes, real/zero/ + negative query vectors and mismatched dimensions. Upstream's four + best-transition budget regressions remain covered. +- A shuffled caller-supplied snapshot returns the same time anchors without + reordering the caller's slice. Decode tests exercise growth, shrinkage, + invalid bytes, signed zero, subnormals, infinities and NaNs. +- Existing index-plan/migration, bounded-BFS parity, transaction rollback/panic + and supersedes/compaction tests pass. Equal-score anchor/result order still + has the pre-existing nondeterminism; no byte-for-byte ordering claim is added. + +To reproduce this comparison, use the commands in the historical reproduction +section with **`5c98ff9c` as the baseline and `9393edbe` as the optimized revision**. +Copy the unchanged `performance*_test.go` files from `a21d783b` into the baseline +archive, compile separate binaries and alternate their execution. Paid live +providers, cold filesystem-cache timing and the Agency/Docker integration +umbrella remain outside these measurements. + +## Historical audit: 4d312c4e → 766c3965 + +The rest of this document records the original experiment before the master +sync. Its timings and gains apply only to those historical revisions. In +particular, the original 6.51× dense-recall gain is **not** the incremental gain +over current master; use the fresh comparison above for that decision. + This audit covers the native Memory read/write pipeline: SQLite retrieval, keyword and vector scoring, multi-signal recall, semantic candidates, bounded graph traversal, graph writes and retention. Agency authorization, replay and @@ -12,7 +183,7 @@ daemon protocols are outside this change. There is no claim of a universally optimal implementation: input size, graph density, selectivity and durability requirements impose different costs. -## What changed +### What changed 1. Replace three single-column insight indexes with indexes matching active timestamp, source/timestamp and importance/timestamp reads. Remove the old @@ -47,7 +218,7 @@ order; the old code already combined unordered maps and non-stable sorts. The optimization does not add approximate nearest-neighbor search or discard low-ranked candidates before a stage that needs them for score normalization. -## Complexity audit +### Complexity audit Let **N** be active insights, **E** graph edges, **L** average text/tag/entity size, **d** embedding dimensions, **Q** query tokens and **K** requested results. @@ -96,7 +267,7 @@ on the neighborhood, including missing/deleted endpoints, rather than unrelated history. A high-degree node can still be expensive. Unlimited BFS retains its bulk `O(NL + E)` loading and traversal path. -## Measurement method +### Measurement method The committed [benchmarks](../../internal/memory/performance_test.go) use real temporary SQLite WAL databases and synthetic local vectors. N is **corpus size**, @@ -132,7 +303,7 @@ are used together; timing ratios are local observations, not latency promises. `B/op` is cumulative Go allocation per operation, **not peak RSS** or database file size. Three timing points alone cannot establish a Big-O bound. -### N=1, 10, 100 +#### N=1, 10, 100 CPU **µs/op**, before → after. Each cell is a median of five runs. @@ -160,7 +331,7 @@ CPU **µs/op**, before → after. Each cell is a median of five runs. | Retention | 58.2 → 59.0 | 151.9 → 149.6 | 1,134.6 → 1,104.2 | | EngineProvided | 97.0 → 85.8 | 388.3 → 300.7 | 1,004.4 → 637.8 | -### Larger corpus and allocation results +#### Larger corpus and allocation results CPU **ms/op**, before → after; allocation is **KiB/op** at N=10,000. Speedup is before CPU / after CPU, not a throughput SLA. @@ -188,7 +359,7 @@ CPU **ms/op**, before → after; allocation is **KiB/op** at N=10,000. Speedup i | Retention | 11.675 → 11.813 | 184.412 → 185.037 | 1.00× | 20,025.9 → 20,025.9 | | EngineProvided | 3.369 → 0.814 | 56.044 → 2.029 | 27.62× | 290.9 → 51.4 | -### Dense graph and unchanged controls +#### Dense graph and unchanged controls | Dense recall | CPU ms/op, before → after | CPU speedup | KiB/op, before → after | |---|---:|---:|---:| @@ -221,7 +392,7 @@ saved as [before](benchmarks/2026-10-03-memory-before.txt) and [after](benchmarks/2026-10-03-memory-after.txt). No exploratory or superseded implementation measurements are mixed into these files. -## Correctness and verification +### Correctness and verification - `go build -o mnemon .` — passed. - `make test` — passed, including vet, deterministic tests and architecture @@ -245,7 +416,7 @@ run; these changes do not modify those boundaries. The Memory CLI boundary was exercised directly. The changes do not add goroutines or change transaction commit policy, supersession authority or exact-duplicate write suppression. -## Reproduce +### Reproduce On the PR revision: @@ -265,7 +436,7 @@ with `-test.run='^$' -test.bench=BenchmarkMemory -test.benchmem rounds. Compare medians of the identically named cases. Do not run other test suites concurrently with the measurements. -## Remaining limits +### Remaining limits Exact keyword/vector matching, JSON entity misses and retention still have whole-corpus work. Persistent token/entity indexes would need their own diff --git a/docs/zh/development/memory-algorithm-performance.md b/docs/zh/development/memory-algorithm-performance.md index d9561854..a988e734 100644 --- a/docs/zh/development/memory-algorithm-performance.md +++ b/docs/zh/development/memory-algorithm-performance.md @@ -1,94 +1,101 @@ # Memory 算法性能调优报告 -日期:2026-10-03。在独立 worktree、分支 -`codex/memory-algorithm-performance` 中完成。基线为 `4d312c4e`,最终算法实现为 -`766c3965`。范围覆盖 Memory 的查询、存储、关键词/向量召回、图遍历、语义候选和 -保留策略;不修改 Agency 的授权、重放或 daemon 协议。 +更新日期:2026-10-03。独立 worktree 中的性能分支已同步默认分支 `master` +(仓库没有使用 `main` 这个名称),基线为 `5c98ff9c`,合并提交为 `6d1511ac`, +最终算法实现为 `9393edbe`。 -[完整复杂度分析、全部测试表格、原始数据和复现方式](../../development/memory-algorithm-performance.md) -保存在英文报告中。 +[完整分析、历史对照、原始数据和复现方式](../../development/memory-algorithm-performance.md) +保存在英文报告中。本页主表以最新 `master` 为基线,旧报告的大幅提升倍数 +不再当作相对当前主线的增量收益。 -## 结论 +## 同步与新增优化 -可以在保持评分公式、阈值、遍历预算、过期内容降权和事务提交规则的前提下继续优化。 -本次主要消除了重复读取、重复评分、无必要的全量排序和逐行 SQL 编译。没有引入 -近似向量检索,也没有用缩减候选数量的方式牺牲召回质量。 +主线已经合入邻接覆盖索引、同一请求内的转移缓存、调用方记录快照复用、模型 +keep-alive 和数据库压缩。这些改动完整保留,收益计入基线。 -不能把这理解为所有路径都达到“绝对最优”:精确向量匹配仍需扫描向量,实体与 -子串未命中仍可能扫描全库,持久化和图密度也有实际成本。报告区分了复杂度下降、 -常数优化和未改变的成本。 +合并冲突时保留了主线的关键规则:**先按意图和相似度排列完整邻域,再应用访问 +预算**。同分时仍按记录 ID、边类型排列。在这个规则下复用本 PR 已计算的余弦 +标量分数,避免为每条边重复计算相似度,也避免维护两套邻接缓存。 -## N=1、10、100 的验证 +本轮另外复用了向量解码缓冲区:同一请求内逐条解码、立即计算分数,然后复用数组。 +存储格式、浮点计算顺序和缓存生命周期保持不变。与刚合并主线的版本单独比较, +N=10,000 混合召回的单次分配从约 59.35 MB 降到 49.11 MB,减少约 17%。 +这是累计内存分配量,不是进程峰值内存。 -N 表示活跃记录数,不是重复运行次数。以下是单次操作的 **CPU 微秒**,格式为 -“优化前 → 优化后”,取 5 轮中位数。 +## 再次测量 -| 路径 | N=1 | N=10 | N=100 | -|---|---:|---:|---:| -| 关键词检索 | 4.2 → 3.4 | 37.8 → 30.4 | 355.8 → 290.2 | -| 混合召回 | 78.2 → 75.6 | 919.5 → 283.5 | 6,144.7 → 2,253.8 | -| WHY 召回 | 43.7 → 42.0 | 1,121.4 → 344.5 | 7,561.7 → 2,357.0 | -| 两跳邻域 | 17.0 → 14.8 | 49.4 → 57.7 | 359.3 → 58.8 | -| N 条记录的原子插入 | 74.8 → 75.0 | 266.4 → 171.7 | 2,246.0 → 1,203.7 | +N 是记录数;使用 N=1、10、100、1,000、10,000,108 个用例,每个版本交替 +运行 5 轮,共 **1,080 个最终样本**。下面为 CPU 时间中位数;MB 使用十进制。 +机器、数据和脚本与原审计一致,使用真实临时 SQLite WAL 和 128 维本地向量。 -另外测试了 N=1,000、10,000,避免用小样本的固定开销推断复杂度。N=10,000 的 -结果如下,单位为 **CPU 毫秒**;倍数是前后 CPU 时间之比。 +单位:**CPU 微秒/次**,最新主线 → 最终 PR。 -| 路径 | 优化前 | 优化后 | 倍数 | +| 路径 | N=1 | N=10 | N=100 | +|---|---:|---:|---:| +| 按重要性取前 10 条 | 22.9 → 21.4 | 45.6 → 42.3 | 50.1 → 41.4 | +| 同来源最新记录 | 15.9 → 14.4 | 15.9 → 14.7 | 21.0 → 14.6 | +| 关键词检索 | 4.3 → 3.4 | 37.8 → 30.2 | 361.6 → 288.7 | +| 混合召回 | 82.2 → 80.0 | 339.3 → 316.2 | 3,037.5 → 2,555.0 | +| WHY 召回 | 47.7 → 45.9 | 453.9 → 423.5 | 3,236.2 → 2,687.0 | +| 向量语义候选 | 11.6 → 13.4 | 54.0 → 53.5 | 70.6 → 64.0 | +| 两跳邻域 | 17.4 → 15.2 | 50.1 → 59.3 | 368.4 → 59.3 | +| N 条原子插入 | 75.7 → 76.6 | 278.9 → 177.5 | 2,291.2 → 1,185.3 | + +N=10,000,单位:**CPU 毫秒/次**。 + +| 路径 | 主线 | 最终 PR | 倍数 | |---|---:|---:|---:| -| 按来源取最新记录 | 1.193 | 0.0146 | 81.60× | -| 按重要性取前 10 条 | 2.294 | 0.040 | 57.33× | -| 混合召回 | 101.097 | 73.694 | 1.37× | -| 向量语义候选 | 1.892 | 0.962 | 1.97× | -| 两跳邻域 | 45.634 | 0.0583 | 782.60× | -| 10,000 条原子插入 | 550.995 | 458.416 | 1.20× | -| 显式提供实体的图写入流程 | 56.044 | 2.029 | 27.62× | - -额外的稠密图测试在 N=100 时,混合召回从 126.394 ms 降到 19.429 ms,约 6.51×。 -每次分配从约 65.3 MiB 降到 9.8 MiB。普通 N=10,000 混合召回的每次分配从约 -75.7 MiB 降到 56.7 MiB;局部邻域从 23,987,320 字节降到 9,504 字节。 -这些是累计分配量,不是进程峰值内存。 - -## 实施的优化与复杂度 - -- **有序数据库查询**:用活跃记录的时间、来源/时间、重要性/时间复合索引替换三个 - 单列索引。匹配这些索引的有限查询从扫描候选并排序,变为约 `O(log N + K)`; - 全部活跃记录的时间排序读取从 `O(N log N)` 的排序成本降为线性索引遍历。 -- **局部图遍历**:有限 BFS 只读取实际邻域,不再先加载全部 N 条记录和 E 条边。 - 保留边的插入顺序、类型过滤、最大跳数、数量限制和删除过滤。无限遍历仍批量加载, - 避免把全图遍历变成逐节点 SQL 查询。 -- **多路召回**:关键词与余弦相似度只计算一次,保存标量分数;同一请求的多个锚点 - 共用邻接查询结果和已加载的记录。每个锚点仍有独立的 visited 集合及预算。 - 假设 X 次图转移、d 维向量,重复余弦计算的主要成本由 `O((N+X)d)` 降为 - `O(Nd+X)`。缓存随请求结束,不跨命令保留过期状态。 -- **语义候选与 Diff**:前 K 名选择由全量排序改为有界堆,选择成本从 - `O(M log M)` 降为 `O(M log K)`,选择存储从 `O(M)` 降为 `O(K)`。 - K=5 时,N=1/10/100/1,000/10,000 的比较次数实测为 - 0/37/440/4,491/44,991;CI 检查操作次数上界,不以脆弱的计时阈值判定成功。 -- **写入**:事务内按需预编译并复用记录/边插入语句,提交或回滚后释放。 - 批量插入仍有 `O(B log(N+B))` 的索引工作,但不再为每行重复编译相同 SQL。 - 显式提供实体时跳过无用途的全库实体提取。 - -固定查询与结果限额下,关键词检索仍随文本总量线性增长;精确向量扫描仍是 -`O(Nd)`。保留策略刷新仍需聚合边、更新记录、排序候选,一般为 `O(E+N log N)`。 -自动裁剪的活跃计数仍有 `O(N)` 成本。逐条精确比对的批量导入仍可能有 -`O(BN+B²)` 的累计工作。这些路径没有被包装成“常数时间”。 - -## 取舍、测量与验证 - -测试使用 Apple M4、Go 1.25.4、单 P、真实临时 SQLite WAL 数据库和 128 维本地 -合成向量,交替运行前后版本。记录实际耗时、进程 CPU 时间及分配量,共 -108 个用例 × 5 轮 × 2 个版本。不调用付费模型,不计入 CLI 启动、网络和冷缓存。 -机器是共享开发环境,所以这些数字是本机观测,不能直接作为线上延迟承诺。 - -小规模存在固定开销取舍:N=10 的局部 BFS 多约 8.3 µs;单条语义查询多约 -1.6 µs。N=10,000 的未命中 LIKE 查询仍是线性扫描,本轮 CPU 约慢 4%。 -这些结果均保留在报告中。更宽的索引最初增加了批量写入成本;加入事务内语句复用后, -最终 10,000 条插入的 CPU 比基线减少约 17%。 - -已通过单文件产品构建、`make test`、Memory 和命令层的 race 测试,以及全部 -258 项 CLI E2E 断言。新增测试覆盖四种意图与预算下的新旧遍历等价性、图环路、 -已删除/缺失节点、查询间缓存刷新、跨时区排序、索引迁移、事务回滚和 panic 清理。 -原有等分/同时间候选的相对顺序没有确定性保证,本次也不作逐字节排序不变的承诺。 - -没有运行不受本次改动影响的 Agency/Docker 集成总入口和付费 live 套件。 +| 按重要性取前 10 条 | 0.9576 | 0.0398 | 24.04× | +| 同来源最新记录 | 0.6016 | 0.0146 | 41.35× | +| 关键词检索 | 33.7453 | 26.5098 | 1.27× | +| 混合召回 | 93.0620 | 66.5310 | 1.40× | +| WHY 召回 | 91.0855 | 67.1605 | 1.36× | +| 向量语义候选 | 1.8507 | 0.9890 | 1.87× | +| 两跳邻域 | 40.3057 | 0.0595 | 677.77× | +| N 条原子插入 | 524.3310 | 431.6040 | 1.21× | +| 显式提供实体的图写入 | 37.8323 | 2.3085 | 16.39× | + +稠密图 N=100 的混合召回为 18.324 → 16.866 ms,约 1.09×。主线 +已经带来大部分图缓存收益,因此不再沿用旧基线的 6.51×。普通 N=10,000 混合 +召回的累计分配为 78.85 → 49.10 MB,减少 37.7%。 + +小规模仍有取舍:N=10 邻域查询为 50.09 → 59.34 µs;N=1 向量/文本语义路径 +分别为 11.57 → 13.36 µs、11.75 → 13.79 µs。N=10,000 实体集合扫描约慢 +4%,保留策略接近持平(170.104 → 171.657 ms)。这些退化保留在数据中。 +未改算法的向量读取也有时间波动,不能把较小的差别全部归因于算法。以上是共享 +开发机器上的观测,不是线上延迟承诺。 + +完整最终数据:[主线](../../development/benchmarks/2026-10-03-memory-main.txt)、 +[最终 PR](../../development/benchmarks/2026-10-03-memory-synced.txt)。额外的解码缓冲 +对照采用 3 轮、200 ms,每轮测混合/WHY 召回;它没有混入上述最终样本。 + +## 当前复杂度结论 + +| 部分 | 相对当前主线的变化与限制 | +|---|---| +| 来源/时间、重要性/时间的有限查询 | 兼容索引的查询约为 `O(log N + K)`;全库时间排序改为顺序索引扫描 | +| 多路召回 | 主线已有邻接缓存。设 E_U 为展开节点读到的邻边数,余弦相关成本从 `O((N+E_U+C)d)` 降为 `O(Nd+E_U+C)`;每个邻域的完整排序仍保留 | +| 精确向量扫描 | 仍是 `O(Nd)`;固定维度下,临时解码数组的累计分配从 `O(Nd)` 降为 `O(d)` | +| 语义候选与 Diff | 前 K 名的选择从 `O(M log M)` 改为 `O(M log K)`,选择空间从 `O(M)` 降为 `O(K)` | +| 有限 BFS | 按实际邻域读记录与边,保留原插入顺序、节点/深度限额;不再随无关的全库规模加载数据。高出度仍有成本 | +| 原子写入 | 事务内复用预编译语句;索引维护仍有 `O(B log(N+B))` 工作及提交 I/O | +| 未命中、保留策略、导入 | 子串/实体未命中仍可能全库扫描;保留策略一般 `O(E+N log N)`,逐条精确比对的批量导入仍可能 `O(BN+B²)` | + +关键词与精确向量检索没有改成近似算法。访问预算限制访问数量,但不能免除读取、 +排列高出度邻域的成本。小规模耗时不足以独立证明 Big-O,结论还结合代码、查询 +计划、分配量和确定性的操作计数。 + +## 验证 + +- 最终实现通过 `go build -o mnemon .`、`make test`、Memory/命令层 race 检查, + 以及全部 **258 项 CLI E2E** 断言。 +- npm 测试 **13 项通过**;上游 OpenCode 运行时和 ZCode shell hook 套件在本机 + 通过。macOS 上跳过了 Windows PowerShell 专用探针,未将其写为已通过。 +- 独立遍历对照已更新为主线 `5c98ff9c`,覆盖四种意图、三档预算、重叠锚点、 + 同分、环路、删除节点、零/负相似度及维度不匹配,分数和来源标签一致。 +- 验证调用方无序快照不被修改、时间锚点结果不变,以及解码数组扩缩容、非法数据、 + 有符号零、非正规数、无穷和 NaN 的位值。原有索引迁移、事务回滚、压缩和 BFS + 等价性检查也通过。 + +保留原有等分锚点/结果顺序的不确定性,不承诺逐字节排序不变。未调用付费模型, +未运行 Agency/Docker 集成总入口;基准不包含 CLI 启动、网络或冷文件缓存。