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/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/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 new file mode 100644 index 00000000..febb9a2a --- /dev/null +++ b/docs/development/memory-algorithm-performance.md @@ -0,0 +1,449 @@ +# Memory algorithm performance audit + +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 +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..a988e734 --- /dev/null +++ b/docs/zh/development/memory-algorithm-performance.md @@ -0,0 +1,101 @@ +# Memory 算法性能调优报告 + +更新日期:2026-10-03。独立 worktree 中的性能分支已同步默认分支 `master` +(仓库没有使用 `main` 这个名称),基线为 `5c98ff9c`,合并提交为 `6d1511ac`, +最终算法实现为 `9393edbe`。 + +[完整分析、历史对照、原始数据和复现方式](../../development/memory-algorithm-performance.md) +保存在英文报告中。本页主表以最新 `master` 为基线,旧报告的大幅提升倍数 +不再当作相对当前主线的增量收益。 + +## 同步与新增优化 + +主线已经合入邻接覆盖索引、同一请求内的转移缓存、调用方记录快照复用、模型 +keep-alive 和数据库压缩。这些改动完整保留,收益计入基线。 + +合并冲突时保留了主线的关键规则:**先按意图和相似度排列完整邻域,再应用访问 +预算**。同分时仍按记录 ID、边类型排列。在这个规则下复用本 PR 已计算的余弦 +标量分数,避免为每条边重复计算相似度,也避免维护两套邻接缓存。 + +本轮另外复用了向量解码缓冲区:同一请求内逐条解码、立即计算分数,然后复用数组。 +存储格式、浮点计算顺序和缓存生命周期保持不变。与刚合并主线的版本单独比较, +N=10,000 混合召回的单次分配从约 59.35 MB 降到 49.11 MB,减少约 17%。 +这是累计内存分配量,不是进程峰值内存。 + +## 再次测量 + +N 是记录数;使用 N=1、10、100、1,000、10,000,108 个用例,每个版本交替 +运行 5 轮,共 **1,080 个最终样本**。下面为 CPU 时间中位数;MB 使用十进制。 +机器、数据和脚本与原审计一致,使用真实临时 SQLite WAL 和 128 维本地向量。 + +单位:**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 | 倍数 | +|---|---:|---:|---:| +| 按重要性取前 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 启动、网络或冷文件缓存。 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/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/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/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 new file mode 100644 index 00000000..a5ed64db --- /dev/null +++ b/internal/memory/performance_test.go @@ -0,0 +1,251 @@ +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 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()) + 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 }}, + {"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 { + 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() + benchmarkMemoryOperation(b, tc.run) + }) + } + }) + } +} + +// 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() + 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 { + return err + } + } + return nil + }); 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 + }) + }) + } +} 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 1930e702..408756f5 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, activeMap(t, db), map[string][]recallTransition{}) + newRecallCache(db, nil, nil, weights).beamSearchFromAnchor("bs-1", 1.0, 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, activeMap(t, db), map[string][]recallTransition{}) + newRecallCache(db, nil, nil, weights).beamSearchFromAnchor("bw-center", 1.0, 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, activeMap(t, db), map[string][]recallTransition{}) + newRecallCache(db, nil, nil, weights).beamSearchFromAnchor("mv-0", 1.0, params, scoreMap, viaMap) // scoreMap includes the anchor itself, so discovered nodes (excluding anchor) should be <= 4 discovered := len(scoreMap) - 1 // subtract anchor @@ -612,18 +609,3 @@ func scoreOf(results []RecallResult, id string) float64 { } return 0 } - -// activeMap indexes the store's active insights the way IntentAwareRecallFrom -// hands them to beam search. -func activeMap(t *testing.T, db *store.DB) map[string]*model.Insight { - t.Helper() - all, err := db.GetAllActiveInsights() - if err != nil { - t.Fatal(err) - } - m := make(map[string]*model.Insight, len(all)) - for _, ins := range all { - m[ins.ID] = ins - } - return m -} 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 c75134e9..c1597743 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" ) @@ -155,72 +154,58 @@ func IntentAwareRecallFrom(db *store.DB, all []*model.Insight, query string, que weights := GetWeights(intent) params := getTraversalParams(intent) - activeByID := make(map[string]*model.Insight, len(all)) - for _, ins := range all { - activeByID[ins.ID] = ins - } - - // 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 ranked transitions it visits. + // Full vectors and token sets need not survive their first scoring pass. + cache := newRecallCache(db, all, queryVec, weights) + 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) @@ -235,9 +220,8 @@ func IntentAwareRecallFrom(db *store.DB, all []*model.Insight, query string, que } } else { anchorMap[ins.ID] = &anchor{ - insight: ins, - score: rrfScore, - via: "time", + score: rrfScore, + via: "time", } } } @@ -260,25 +244,20 @@ func IntentAwareRecallFrom(db *store.DB, all []*model.Insight, query string, que // 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. Anchors' neighbourhoods overlap - // heavily, so each node's edges are read from the store once per recall. - edgeCache := make(map[string][]recallTransition) + // Step 3: Beam search from each anchor for id, a := range anchorMap { - beamSearchFromAnchor(db, id, a.score, queryVec, weights, params, scoreMap, viaMap, insightMap, embedCache, activeByID, edgeCache) + cache.beamSearchFromAnchor(id, a.score, 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 @@ -300,7 +279,7 @@ func IntentAwareRecallFrom(db *store.DB, all []*model.Insight, query string, que var graphMin, graphMax float64 first := true for id, graphRaw := range scoreMap { - ins, ok := insightMap[id] + ins, ok := cache.insights[id] if !ok { continue } @@ -330,20 +309,8 @@ func IntentAwareRecallFrom(db *store.DB, all []*model.Insight, query string, que 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 { @@ -356,14 +323,9 @@ func IntentAwareRecallFrom(db *store.DB, all []*model.Insight, query string, que 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 @@ -518,25 +480,14 @@ 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). -// activeByID resolves neighbours without a query; a neighbour missing from it -// is soft-deleted and never enters insightMap. edgeCache memoises scored edge -// transitions across anchors within one recall. -func beamSearchFromAnchor( - db *store.DB, +// beamSearchFromAnchor keeps traversal budgets and per-anchor visited sets local; +// ranked transitions and similarities are reused 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, - activeByID map[string]*model.Insight, - edgeCache map[string][]recallTransition, ) { visited := map[string]bool{startID: true} totalVisited := 1 @@ -563,14 +514,9 @@ func beamSearchFromAnchor( break } - transitions, cached := edgeCache[cur.id] - if !cached { - edges, err := db.GetNeighborEdges(cur.id) - if err != nil { - continue - } - transitions = rankRecallTransitions(cur.id, edges, queryVec, weights, embedCache) - edgeCache[cur.id] = transitions + transitions, err := cache.transitionsFor(cur.id) + if err != nil { + continue } for _, transition := range transitions { @@ -584,11 +530,6 @@ func beamSearchFromAnchor( if existing, ok := scoreMap[neighborID]; !ok || neighborScore > existing { scoreMap[neighborID] = neighborScore viaMap[neighborID] = string(transition.edgeType) - if _, loaded := insightMap[neighborID]; !loaded { - if ins, ok := activeByID[neighborID]; ok { - insightMap[neighborID] = ins - } - } } if !visited[neighborID] { @@ -677,28 +618,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_budget_test.go b/internal/memory/search/recall_budget_test.go index 3d04f0c0..0dc38dbd 100644 --- a/internal/memory/search/recall_budget_test.go +++ b/internal/memory/search/recall_budget_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/mnemon-dev/mnemon/internal/memory/embed" "github.com/mnemon-dev/mnemon/internal/memory/model" ) @@ -25,9 +26,8 @@ func TestRecallBudgetKeepsBestTransition(t *testing.T) { t.Run(tc.name, func(t *testing.T) { db := testDB(t) now := time.Now().UTC() - active := make(map[string]*model.Insight) for _, id := range []string{"root", "gold", "noise1", "noise2", "noise3"} { - active[id] = insertInsight(t, db, id, id, "test", 3, nil, now) + insertInsight(t, db, id, id, "test", 3, nil, now) } for i := 1; i <= 3; i++ { if err := db.InsertEdge(&model.Edge{SourceID: "root", TargetID: fmt.Sprintf("noise%d", i), EdgeType: model.EdgeEntity, Weight: 1, CreatedAt: now}); err != nil { @@ -42,15 +42,15 @@ func TestRecallBudgetKeepsBestTransition(t *testing.T) { t.Fatal(err) } var query []float64 - var embeddings map[string][]float64 if tc.vector { query = []float64{1, 0} - embeddings = map[string][]float64{"gold": {1, 0}} + if err := db.UpdateEmbedding("gold", embed.SerializeVector(query)); err != nil { + t.Fatal(err) + } } scores := map[string]float64{"root": 1} via := map[string]string{} - insights := map[string]*model.Insight{"root": active["root"]} - beamSearchFromAnchor(db, "root", 1, query, GetWeights(tc.intent), TraversalParams{BeamWidth: 2, MaxDepth: 1, MaxVisited: 3}, scores, via, insights, embeddings, active, make(map[string][]recallTransition)) + newRecallCache(db, nil, query, GetWeights(tc.intent)).beamSearchFromAnchor("root", 1, TraversalParams{BeamWidth: 2, MaxDepth: 1, MaxVisited: 3}, scores, via) if _, ok := scores["gold"]; !ok { t.Fatalf("best transition excluded by visit budget: scores=%v", scores) } diff --git a/internal/memory/search/recall_cache.go b/internal/memory/search/recall_cache.go new file mode 100644 index 00000000..76a7f549 --- /dev/null +++ b/internal/memory/search/recall_cache.go @@ -0,0 +1,65 @@ +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 + transitions map[string][]recallTransition + weights IntentWeights + similarities map[string]float64 +} + +func newRecallCache(db *store.DB, all []*model.Insight, queryVec []float64, weights IntentWeights) *recallCache { + c := &recallCache{ + db: db, insights: make(map[string]*model.Insight, len(all)), + transitions: make(map[string][]recallTransition), weights: weights, + } + for _, ins := range all { + c.insights[ins.ID] = ins + } + if queryVec != nil { + c.similarities = loadQuerySimilarities(db, queryVec) + } + return c +} + +// transitionsFor keeps the complete intent-ranked neighborhood, as upstream +// requires before applying the per-anchor visit budget. Query and intent are +// fixed for this cache, so both ordering and deltas can be reused across anchors. +func (c *recallCache) transitionsFor(id string) ([]recallTransition, error) { + if transitions, ok := c.transitions[id]; ok { + return transitions, nil + } + edges, err := c.db.GetNeighborEdges(id) + if err != nil { + return nil, err // Failed reads may be retried by another anchor. + } + transitions := rankRecallTransitions(id, edges, c.weights, c.similarities) + c.transitions[id] = transitions // Retain empty neighborhoods too. + return transitions, nil +} + +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.DeserializeVectorInto(blob, decoded); vec != nil { + decoded = vec + 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..20ab8c2d --- /dev/null +++ b/internal/memory/search/recall_cache_test.go @@ -0,0 +1,204 @@ +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 i := 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 i%3 == 0 { + e.Weight = 0.5 // Exercise upstream's deterministic transition tie ordering. + } + 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}, {0, 0, 0}, {-0.1, -0.5, -0.9}} { + 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, GetWeights(intent)) + gotScores, wantScores := map[string]float64{}, map[string]float64{} + gotVia, wantVia := map[string]string{}, map[string]string{} + wantInsights := map[string]*model.Insight{} + wantActive := make(map[string]*model.Insight, len(all)) + for _, ins := range all { + wantActive[ins.ID] = ins + } + wantTransitions := make(map[string][]referenceRecallTransition) + for _, anchor := range []string{"n-00", "n-01", "n-07", "n-00"} { + cache.beamSearchFromAnchor(anchor, 1, params, gotScores, gotVia) + referenceBeamSearch(db, anchor, 1, queryVec, GetWeights(intent), params, wantScores, wantVia, wantInsights, vectors, wantActive, wantTransitions) + } + 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) + } +} + +// The CLI now passes an already-loaded snapshot to recall. An out-of-order +// snapshot must retain time-anchor selection without mutating the caller's slice. +func TestRecallFromSnapshotPreservesTimeAnchorsAndInput(t *testing.T) { + db := testDB(t) + base := time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC) + for i := 0; i < anchorTopK+3; i++ { + insertInsight(t, db, fmt.Sprintf("snapshot-%02d", i), "record", "test", 3, nil, base.Add(time.Duration(i)*time.Minute)) + } + all, err := db.GetAllActiveInsights() + if err != nil { + t.Fatal(err) + } + rng := rand.New(rand.NewSource(43)) + rng.Shuffle(len(all), func(i, j int) { all[i], all[j] = all[j], all[i] }) + original := append([]*model.Insight(nil), all...) + want, err := IntentAwareRecall(db, "", nil, nil, 0, nil) + if err != nil { + t.Fatal(err) + } + got, err := IntentAwareRecallFrom(db, all, "", nil, nil, 0, nil) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("caller snapshot changed recall: got=%+v want=%+v", got, want) + } + if !reflect.DeepEqual(all, original) { + t.Fatal("recall reordered the caller's snapshot") + } +} diff --git a/internal/memory/search/recall_reference_test.go b/internal/memory/search/recall_reference_test.go new file mode 100644 index 00000000..36eaf0dd --- /dev/null +++ b/internal/memory/search/recall_reference_test.go @@ -0,0 +1,143 @@ +package search + +import ( + "container/heap" + "sort" + + "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 and referenceRankRecallTransitions preserve the traversal +// and intent-ranked visit budget from upstream 5c98ff9c. Keep their full-vector +// cosine calculations independent of the production scalar/transition cache. +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, + activeByID map[string]*model.Insight, + edgeCache map[string][]referenceRecallTransition, +) { + 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 + } + + transitions, cached := edgeCache[cur.id] + if !cached { + edges, err := db.GetNeighborEdges(cur.id) + if err != nil { + continue + } + transitions = referenceRankRecallTransitions(cur.id, edges, queryVec, weights, embedCache) + edgeCache[cur.id] = transitions + } + + for _, transition := range transitions { + if totalVisited >= params.MaxVisited { + break + } + neighborID := transition.id + neighborScore := cur.score + transition.delta + + // Update global score map if this path is better + if existing, ok := scoreMap[neighborID]; !ok || neighborScore > existing { + scoreMap[neighborID] = neighborScore + viaMap[neighborID] = string(transition.edgeType) + if _, loaded := insightMap[neighborID]; !loaded { + if ins, ok := activeByID[neighborID]; ok { + 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 + } +} + +type referenceRecallTransition struct { + id string + edgeType model.EdgeType + delta float64 +} + +// referenceRankRecallTransitions applies the same intent and similarity terms as beam +// scoring before the visit budget can discard a neighbour. The ordering and +// deltas are reusable across anchors within this one recall, whose query and +// intent do not change. The current path score is added by the caller. +func referenceRankRecallTransitions(nodeID string, edges []*model.Edge, query []float64, + weights IntentWeights, embeddings map[string][]float64) []referenceRecallTransition { + transitions := make([]referenceRecallTransition, 0, len(edges)) + for _, e := range edges { + id := e.TargetID + if id == nodeID { + id = e.SourceID + } + delta := lambda1 * weights[e.EdgeType] * e.Weight + if query != nil { + if vector, ok := embeddings[id]; ok { + if similarity := embed.CosineSimilarity(query, vector); similarity > 0 { + delta += lambda2 * similarity + } + } + } + transitions = append(transitions, referenceRecallTransition{id: id, edgeType: e.EdgeType, delta: delta}) + } + sort.Slice(transitions, func(i, j int) bool { + a, b := transitions[i], transitions[j] + if a.delta != b.delta { + return a.delta > b.delta + } + if a.id != b.id { + return a.id < b.id + } + return a.edgeType < b.edgeType + }) + return transitions +} diff --git a/internal/memory/search/recall_transition.go b/internal/memory/search/recall_transition.go index 53346ae2..e39a9b28 100644 --- a/internal/memory/search/recall_transition.go +++ b/internal/memory/search/recall_transition.go @@ -3,7 +3,6 @@ package search import ( "sort" - "github.com/mnemon-dev/mnemon/internal/memory/embed" "github.com/mnemon-dev/mnemon/internal/memory/model" ) @@ -17,8 +16,8 @@ type recallTransition struct { // scoring before the visit budget can discard a neighbour. The ordering and // deltas are reusable across anchors within this one recall, whose query and // intent do not change. The current path score is added by the caller. -func rankRecallTransitions(nodeID string, edges []*model.Edge, query []float64, - weights IntentWeights, embeddings map[string][]float64) []recallTransition { +func rankRecallTransitions(nodeID string, edges []*model.Edge, + weights IntentWeights, similarities map[string]float64) []recallTransition { transitions := make([]recallTransition, 0, len(edges)) for _, e := range edges { id := e.TargetID @@ -26,12 +25,8 @@ func rankRecallTransitions(nodeID string, edges []*model.Edge, query []float64, id = e.SourceID } delta := lambda1 * weights[e.EdgeType] * e.Weight - if query != nil { - if vector, ok := embeddings[id]; ok { - if similarity := embed.CosineSimilarity(query, vector); similarity > 0 { - delta += lambda2 * similarity - } - } + if similarity := similarities[id]; similarity > 0 { + delta += lambda2 * similarity } transitions = append(transitions, recallTransition{id: id, edgeType: e.EdgeType, delta: delta}) } diff --git a/internal/memory/store/db.go b/internal/memory/store/db.go index 20ad6106..bff0e64f 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() @@ -311,10 +341,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_type ON edges(edge_type); CREATE INDEX IF NOT EXISTS idx_edges_source_type ON edges(source_id, edge_type); CREATE INDEX IF NOT EXISTS idx_edges_target_type ON edges(target_id, edge_type); diff --git a/internal/memory/store/edge.go b/internal/memory/store/edge.go index c03bcd44..d9cb40ee 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. @@ -67,6 +66,44 @@ func (db *DB) GetNeighborEdges(nodeID string) ([]*model.Edge, error) { return results, rows.Err() } +// 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 +} + // GetSupersededIDs checks only the requested targets, using the covering partial // index when available. A store can accumulate an unbounded supersession history; // unrelated history must not be scanned for a small recall candidate set. 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 72c1fb29..fad5b9b0 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). @@ -835,7 +834,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/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) + } + } +} 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": {},