Skip to content

perf(hnsw): compact outgoing adjacency - #444

Merged
jimezesinachi merged 4 commits into
mainfrom
perf/hnsw-compact-adjacency
Oct 23, 2026
Merged

jimezesinachi merged 4 commits into
mainfrom
perf/hnsw-compact-adjacency

Conversation

@jimezesinachi

@jimezesinachi jimezesinachi commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Per-layer outgoing HNSW neighbor sets allocate a Papaya table, counters, and separate entries for small, bounded lists. Store these lists as immutable ArcSwap<Vec<NodeId>> snapshots to reduce structural memory and improve traversal locality.

The existing Node and HNSW are generic over edge storage, so HashSet control and compact candidate share insertion, search, filtering, deletion, and persistence algorithms. Compact writes use compare-and-swap; pruning recomputes selection if another writer changes the snapshot. Backlinks, outer layer maps, graph-layer sets, embeddings, and IDs retain their existing representations.

DB builds use compact adjacency by default. --features bench-control-adjacency selects the HashSet control for fallback and ghz A/B builds. The previous bench-compact-adjacency flag remains accepted for candidate commands. The persisted TempNode/TempHNSW shape is retained, allowing either representation to restore the other's snapshots.

Criterion and fresh-process memory A/B targets remain registered under bench-experiments; the existing labelled workflow discovers them and posts their reports.

Measured results

Same-run Criterion estimates for deterministic 768-dimensional cosine fixtures:

Workload Control Compact candidate Lower time
Build 1k vectors and drop 377.01 ms 351.39 ms 6.8%
Insert 100 into 2.5k and drop 147.64 ms 135.10 ms 8.5%
Search 16 queries over 10k, efSearch=100 18.933 ms 17.872 ms 5.6%

Construction and incremental insertion timings include index destruction; they do not isolate insertion cost.

Structural allocation, median of three fresh processes, M=16/M0=32/efConstruction=200, shared collectors and one per-node counter shard:

Vectors Control Compact candidate Saving
10k 25.087 MiB 18.086 MiB 7.002 MiB / 27.9%
100k 243.082 MiB 177.897 MiB 65.185 MiB / 26.8%

Memory deltas exclude unchanged embedding payload. Post-drop allocation checks passed. These measurements do not establish whole-DB peak memory or that Cohere 10M fits within 56 GiB. End-to-end ghz c1 results for this final shared implementation are still pending.

Validation

  • 26 focused HNSW tests passed, covering control/candidate topology and results for all three metrics, duplicate inserts, filtering, efSearch, deletion, cross-representation JSON restoration, collector lifecycle, concurrent edge updates, and deterministic pruning retries.
  • DB compilation passed for default compact, explicit control, and the retained candidate flag.
  • All registered similarity benchmark targets compile with bench-experiments.
  • The existing concurrent graph-insertion issue is outside this change; edge-level concurrency tests do not establish concurrent graph-insertion correctness.

Signed-off-by: Jim Ezesinachi <ezesinachijim@gmail.com>
@jimezesinachi jimezesinachi added the benchmark-experiments Trigger opt-in Criterion benchmark comparisons label Oct 21, 2026
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Opt-in Benchmark Results: similarity/hnsw_compact_adjacency_graph

first-time benchmark: candidate vs control

group                                                              pr-39939308454-similarity-hnsw_compact_adjacency_graph/candidate/    pr-39939308454-similarity-hnsw_compact_adjacency_graph/control/
-----                                                              -----------------------------------------------------------------    ---------------------------------------------------------------
hnsw_compact_adjacency_graph/build/1k_768d                         1.00    218.2±1.37ms  4.5 KElem/sec                                  1.10    240.7±3.63ms  4.1 KElem/sec
hnsw_compact_adjacency_graph/existing_insert/2_5k_plus_100_768d    1.00     88.6±0.21ms  1128 Elem/sec                                  1.07     94.8±0.13ms  1055 Elem/sec
hnsw_compact_adjacency_graph/search/10k_768d_ef100                 1.00     10.4±0.04ms  1537 Elem/sec                                  1.11     11.5±0.03ms  1388 Elem/sec

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Opt-in Memory Benchmark Results

similarity/hnsw_compact_adjacency_graph_memory

Whole HNSW structural-memory candidate, 10000 deterministic 768-dimensional vectors, cosine, serial insertion, M=16/M0=32/efConstruction=200, shared collectors, and one per-node counter shard. Median of 3 fresh processes. Both variants build the same topology; vectors are generated before the baseline and remain alive through the measurement, so unchanged float32 payload is excluded.

The candidate replaces only each per-layer outgoing Papaya HashSet<NodeId> with an immutable ArcSwap<Vec<NodeId>>; node outer layer maps, backlinks, graph layer sets, IDs, and construction heuristic remain. Child thread cache is disabled for accounting only. MiB values are allocated / active / jemalloc resident; resident is not process RSS.

Nodes Layer lists Outgoing edges Control MiB Candidate MiB Allocated saving MiB Saving/list bytes Saving/edge bytes
10000 10659 257203 25.067 / 25.191 / 25.816 18.053 / 18.191 / 18.742 7.014 690.0 28.6

This compares steady, post-build structural memory. It excludes vector payload and does not measure concurrent peak memory, persistence, deletion, or whole-DB overhead. Do not extrapolate directly to Cohere 10M.

similarity/hnsw_counter_shards_memory

Detected CPUs: 4; default counter shards: 4; architecture: x86_64.

Median of 3 fresh processes per scenario/variant. All variants share one collector. Control uses default sharding; candidates use one/two shards only for per-node collections. Index-wide collections retain default sharding.

Values are jemalloc deltas from a baseline retaining the input vectors. Active/resident columns are control / one shard / two shards. Resident is jemalloc resident, not process RSS. Fixtures use cosine distance and serial insertion.

Scenario Nodes Per-node collections Expected counter saving MiB: one shard Expected counter saving MiB: two shards
1k_128d_defaults 1000 3053 1.118 0.745
1k_768d_zvec_1m 1000 3071 1.125 0.750
10k_768d_zvec_1m 10000 30716 11.249 7.499

Expected savings cover live per-node counters only, using 128-byte padding on x86_64/ARM64. Retired collections, allocator size classes, and reclamation timing can change the measured delta; this prediction is not whole-index accounting. A negative expectation on a small-CPU machine means the candidate uses more shards than the default.

Scenario Phase Control allocated MiB One shard allocated MiB Saving Two shards allocated MiB Saving Active MiB Resident MiB
1k_128d_defaults populated 3.520 2.402 31.8% 2.790 20.7% 3.727 / 2.605 / 2.996 4.289 / 2.641 / 3.043
1k_128d_defaults after deleting all nodes 0.280 0.279 0.4% 0.271 3.3% 1.484 / 1.480 / 1.477 4.289 / 2.641 / 3.043
1k_128d_defaults after dropping index 0.265 0.278 n/a 0.268 n/a 1.414 / 1.438 / 1.422 4.289 / 2.641 / 3.043
1k_768d_zvec_1m populated 3.508 2.367 32.5% 2.737 22.0% 3.594 / 2.453 / 2.840 3.664 / 2.488 / 2.887
1k_768d_zvec_1m after deleting all nodes 0.261 0.250 3.9% 0.236 9.3% 1.449 / 1.449 / 1.355 3.664 / 2.488 / 2.887
1k_768d_zvec_1m after dropping index 0.255 0.250 n/a 0.233 n/a 1.379 / 1.387 / 1.340 3.664 / 2.488 / 2.887
10k_768d_zvec_1m populated 36.184 24.887 31.2% 28.677 20.7% 36.293 / 25.004 / 28.797 37.785 / 25.750 / 29.543
10k_768d_zvec_1m after deleting all nodes 0.492 0.488 0.8% 0.497 -1.0% 5.887 / 5.816 / 5.984 37.785 / 25.750 / 29.543
10k_768d_zvec_1m after dropping index 0.160 0.188 n/a 0.194 n/a 3.574 / 3.875 / 3.859 37.785 / 25.750 / 29.543

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Test Results

427 tests   427 ✅  11m 33s ⏱️
 42 suites    0 💤
  4 files      0 ❌

Results for commit 922bf4b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Benchmark Results

group                                                        main                                   pr
-----                                                        ----                                   --
predicate_query_with_index/size_100                          1.02      2.2±0.02µs        ? ?/sec    1.00      2.1±0.03µs        ? ?/sec
predicate_query_with_index/size_1000                         1.00     17.7±0.05µs        ? ?/sec    1.13     19.9±0.26µs        ? ?/sec
predicate_query_with_index/size_10000                        1.03    199.6±1.10µs        ? ?/sec    1.00    193.5±2.14µs        ? ?/sec
predicate_query_with_index/size_100000                       1.00      3.1±0.14ms        ? ?/sec    1.01      3.1±0.06ms        ? ?/sec
predicate_query_without_index/size_100                       1.05      4.0±0.02µs        ? ?/sec    1.00      3.8±0.05µs        ? ?/sec
predicate_query_without_index/size_1000                      1.00     39.2±0.43µs        ? ?/sec    1.02     40.1±0.46µs        ? ?/sec
predicate_query_without_index/size_10000                     1.00    630.3±3.74µs        ? ?/sec    1.06    665.2±3.94µs        ? ?/sec
predicate_query_without_index/size_100000                    1.00     20.3±2.29ms        ? ?/sec    1.62     32.9±4.35ms        ? ?/sec
store_batch_insertion_without_predicates/size_100            1.03    108.7±0.95µs        ? ?/sec    1.00    105.0±1.42µs        ? ?/sec
store_batch_insertion_without_predicates/size_1000           1.11    831.8±8.92µs        ? ?/sec    1.00   749.1±13.65µs        ? ?/sec
store_batch_insertion_without_predicates/size_10000          1.07     10.1±0.15ms        ? ?/sec    1.00      9.5±0.24ms        ? ?/sec
store_batch_insertion_without_predicates/size_100000         1.03    101.4±0.88ms        ? ?/sec    1.00     97.9±1.11ms        ? ?/sec
store_retrieval_linear_cosine_similarity/size_100            1.02     15.9±0.06µs        ? ?/sec    1.00     15.5±0.21µs        ? ?/sec
store_retrieval_linear_cosine_similarity/size_1000           1.00     76.7±0.74µs        ? ?/sec    1.01     77.4±0.79µs        ? ?/sec
store_retrieval_linear_cosine_similarity/size_10000          1.00  1327.8±55.31µs        ? ?/sec    1.07  1420.8±28.96µs        ? ?/sec
store_retrieval_linear_cosine_similarity/size_100000         1.00     19.9±0.18ms        ? ?/sec    1.00     19.9±0.15ms        ? ?/sec
store_retrieval_linear_dot_product/size_100                  1.00     12.0±0.23µs        ? ?/sec    1.02     12.2±0.21µs        ? ?/sec
store_retrieval_linear_dot_product/size_1000                 1.00     74.4±0.82µs        ? ?/sec    1.00     74.4±0.71µs        ? ?/sec
store_retrieval_linear_dot_product/size_10000                1.02  1144.9±30.78µs        ? ?/sec    1.00  1123.0±29.35µs        ? ?/sec
store_retrieval_linear_dot_product/size_100000               1.07     18.1±0.51ms        ? ?/sec    1.00     16.9±0.28ms        ? ?/sec
store_retrieval_linear_euclidean_distance/size_100           1.00     14.5±0.25µs        ? ?/sec    1.03     14.9±0.15µs        ? ?/sec
store_retrieval_linear_euclidean_distance/size_1000          1.00     77.3±0.85µs        ? ?/sec    1.00     77.3±0.92µs        ? ?/sec
store_retrieval_linear_euclidean_distance/size_10000         1.00  1243.4±56.15µs        ? ?/sec    1.15  1430.0±60.66µs        ? ?/sec
store_retrieval_linear_euclidean_distance/size_100000        1.01     19.1±0.36ms        ? ?/sec    1.00     18.9±0.21ms        ? ?/sec
store_retrieval_no_condition/size_100                        1.03     16.0±0.11µs        ? ?/sec    1.00     15.5±0.19µs        ? ?/sec
store_retrieval_no_condition/size_1000                       1.04     78.3±0.80µs        ? ?/sec    1.00     75.5±0.36µs        ? ?/sec
store_retrieval_no_condition/size_10000                      1.19  1459.2±54.69µs        ? ?/sec    1.00  1231.4±41.77µs        ? ?/sec
store_retrieval_no_condition/size_100000                     1.13     21.2±0.32ms        ? ?/sec    1.00     18.7±0.21ms        ? ?/sec
store_retrieval_non_linear_hnsw/size_100                     1.06    106.2±0.46µs        ? ?/sec    1.00    100.5±0.97µs        ? ?/sec
store_retrieval_non_linear_hnsw/size_1000                    1.10    232.7±2.76µs        ? ?/sec    1.00    212.3±4.32µs        ? ?/sec
store_retrieval_non_linear_hnsw/size_10000                   1.07    334.2±4.97µs        ? ?/sec    1.00    312.5±5.09µs        ? ?/sec
store_retrieval_non_linear_hnsw/size_100000                  1.46   506.0±15.01µs        ? ?/sec    1.00    346.5±5.29µs        ? ?/sec
store_retrieval_non_linear_kdtree/size_100                   1.07    124.0±0.70µs        ? ?/sec    1.00    116.4±0.18µs        ? ?/sec
store_retrieval_non_linear_kdtree/size_1000                  1.05    579.6±2.05µs        ? ?/sec    1.00   553.9±22.80µs        ? ?/sec
store_retrieval_non_linear_kdtree/size_10000                 1.22      8.1±0.70ms        ? ?/sec    1.00      6.6±0.65ms        ? ?/sec
store_retrieval_non_linear_kdtree/size_100000                1.08    103.6±0.86ms        ? ?/sec    1.00     96.0±2.32ms        ? ?/sec
store_sequential_insertion_without_predicates/size_100       1.03    195.2±3.02µs        ? ?/sec    1.00    189.7±3.23µs        ? ?/sec
store_sequential_insertion_without_predicates/size_1000      1.01   1940.5±9.56µs        ? ?/sec    1.00  1928.0±18.68µs        ? ?/sec
store_sequential_insertion_without_predicates/size_10000     1.02     19.4±0.25ms        ? ?/sec    1.00     19.1±0.26ms        ? ?/sec
store_sequential_insertion_without_predicates/size_100000    1.03    194.4±1.50ms        ? ?/sec    1.00    188.4±3.31ms        ? ?/sec

@deven96 deven96 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Let's promote

Signed-off-by: Jim Ezesinachi <ezesinachijim@gmail.com>
Signed-off-by: Jim Ezesinachi <ezesinachijim@gmail.com>
Signed-off-by: Jim Ezesinachi <ezesinachijim@gmail.com>
@github-actions

Copy link
Copy Markdown

Opt-in Benchmark Results: similarity/hnsw_distance_reuse

PR base vs PR branch

group                                                 main-39939308454-similarity-hnsw_distance_reuse    pr-39939308454-similarity-hnsw_distance_reuse
-----                                                 -----------------------------------------------    ---------------------------------------------
hnsw_distance_reuse/128d/cosine/candidate/100         1.00  1271.6±18.03µs 12.3 KElem/sec                1.03   1303.8±1.63µs 12.0 KElem/sec
hnsw_distance_reuse/128d/cosine/candidate/200         1.01      2.3±0.02ms  6.9 KElem/sec                1.00      2.2±0.00ms  7.0 KElem/sec
hnsw_distance_reuse/128d/cosine/candidate/50          1.00    764.9±3.35µs 20.4 KElem/sec                1.01    771.8±1.48µs 20.2 KElem/sec
hnsw_distance_reuse/128d/cosine/control/100           1.02   1430.0±2.05µs 10.9 KElem/sec                1.00   1395.6±2.39µs 11.2 KElem/sec
hnsw_distance_reuse/128d/cosine/control/200           1.01      2.5±0.04ms  6.2 KElem/sec                1.00      2.5±0.00ms  6.3 KElem/sec
hnsw_distance_reuse/128d/cosine/control/50            1.00    862.0±2.06µs 18.1 KElem/sec                1.00    862.2±1.90µs 18.1 KElem/sec
hnsw_distance_reuse/128d/dotproduct/candidate/100     1.00   1240.2±3.39µs 12.6 KElem/sec                1.01   1248.9±1.19µs 12.5 KElem/sec
hnsw_distance_reuse/128d/dotproduct/candidate/200     1.00      2.2±0.00ms  7.1 KElem/sec                1.01      2.2±0.01ms  7.0 KElem/sec
hnsw_distance_reuse/128d/dotproduct/candidate/50      1.00    769.5±5.69µs 20.3 KElem/sec                1.00    771.7±2.02µs 20.2 KElem/sec
hnsw_distance_reuse/128d/dotproduct/control/100       1.01   1364.7±0.79µs 11.4 KElem/sec                1.00   1354.5±5.97µs 11.5 KElem/sec
hnsw_distance_reuse/128d/dotproduct/control/200       1.00      2.4±0.00ms  6.6 KElem/sec                1.01      2.4±0.00ms  6.5 KElem/sec
hnsw_distance_reuse/128d/dotproduct/control/50        1.02    853.7±3.35µs 18.3 KElem/sec                1.00   836.7±50.39µs 18.7 KElem/sec
hnsw_distance_reuse/128d/euclidean/candidate/100      1.01  1317.7±33.91µs 11.9 KElem/sec                1.00   1306.1±2.47µs 12.0 KElem/sec
hnsw_distance_reuse/128d/euclidean/candidate/200      1.00      2.3±0.01ms  6.9 KElem/sec                1.04      2.4±0.00ms  6.6 KElem/sec
hnsw_distance_reuse/128d/euclidean/candidate/50       1.00    775.2±1.29µs 20.2 KElem/sec                1.02   790.3±10.40µs 19.8 KElem/sec
hnsw_distance_reuse/128d/euclidean/control/100        1.00  1435.1±19.89µs 10.9 KElem/sec                1.01   1442.8±6.94µs 10.8 KElem/sec
hnsw_distance_reuse/128d/euclidean/control/200        1.01      2.5±0.00ms  6.2 KElem/sec                1.00      2.5±0.00ms  6.2 KElem/sec
hnsw_distance_reuse/128d/euclidean/control/50         1.00    857.7±0.77µs 18.2 KElem/sec                1.01   869.4±20.18µs 18.0 KElem/sec
hnsw_distance_reuse/1536d/cosine/candidate/100        1.00   1797.1±3.79µs  8.7 KElem/sec                1.04   1869.5±2.60µs  8.4 KElem/sec
hnsw_distance_reuse/1536d/cosine/candidate/200        1.00      3.0±0.01ms  5.1 KElem/sec                1.03      3.1±0.01ms  5.0 KElem/sec
hnsw_distance_reuse/1536d/cosine/candidate/50         1.00   1141.4±1.78µs 13.7 KElem/sec                1.04   1183.0±4.24µs 13.2 KElem/sec
hnsw_distance_reuse/1536d/cosine/control/100          1.00      2.6±0.01ms  5.9 KElem/sec                1.02      2.7±0.00ms  5.8 KElem/sec
hnsw_distance_reuse/1536d/cosine/control/200          1.00      4.6±0.01ms  3.4 KElem/sec                1.02      4.8±0.01ms  3.3 KElem/sec
hnsw_distance_reuse/1536d/cosine/control/50           1.00   1615.7±1.48µs  9.7 KElem/sec                1.02   1642.9±4.18µs  9.5 KElem/sec
hnsw_distance_reuse/1536d/dotproduct/candidate/100    1.00   1674.8±3.99µs  9.3 KElem/sec                1.06  1768.5±79.18µs  8.8 KElem/sec
hnsw_distance_reuse/1536d/dotproduct/candidate/200    1.00      2.9±0.00ms  5.3 KElem/sec                1.04      3.0±0.03ms  5.1 KElem/sec
hnsw_distance_reuse/1536d/dotproduct/candidate/50     1.01  1099.7±71.63µs 14.2 KElem/sec                1.00   1092.1±1.57µs 14.3 KElem/sec
hnsw_distance_reuse/1536d/dotproduct/control/100      1.00      2.3±0.03ms  6.7 KElem/sec                1.02      2.4±0.08ms  6.5 KElem/sec
hnsw_distance_reuse/1536d/dotproduct/control/200      1.00      4.2±0.01ms  3.7 KElem/sec                1.03      4.3±0.02ms  3.6 KElem/sec
hnsw_distance_reuse/1536d/dotproduct/control/50       1.00  1448.6±33.11µs 10.8 KElem/sec                1.00   1442.7±2.13µs 10.8 KElem/sec
hnsw_distance_reuse/1536d/euclidean/candidate/100     1.00  1934.4±11.44µs  8.1 KElem/sec                1.04      2.0±0.02ms  7.8 KElem/sec
hnsw_distance_reuse/1536d/euclidean/candidate/200     1.00      3.2±0.01ms  4.8 KElem/sec                1.03      3.4±0.00ms  4.7 KElem/sec
hnsw_distance_reuse/1536d/euclidean/candidate/50      1.00  1245.2±10.47µs 12.5 KElem/sec                1.03  1279.7±23.98µs 12.2 KElem/sec
hnsw_distance_reuse/1536d/euclidean/control/100       1.00      2.8±0.02ms  5.5 KElem/sec                1.02      2.9±0.00ms  5.4 KElem/sec
hnsw_distance_reuse/1536d/euclidean/control/200       1.00      4.9±0.02ms  3.2 KElem/sec                1.02      5.1±0.02ms  3.1 KElem/sec
hnsw_distance_reuse/1536d/euclidean/control/50        1.00  1755.0±21.29µs  8.9 KElem/sec                1.02   1784.7±3.14µs  8.8 KElem/sec
hnsw_distance_reuse/768d/cosine/candidate/100         1.00   1493.2±3.17µs 10.5 KElem/sec                1.04   1548.4±3.82µs 10.1 KElem/sec
hnsw_distance_reuse/768d/cosine/candidate/200         1.00      2.6±0.01ms  6.1 KElem/sec                1.06      2.7±0.02ms  5.7 KElem/sec
hnsw_distance_reuse/768d/cosine/candidate/50          1.00   970.0±14.52µs 16.1 KElem/sec                1.04   1009.1±0.82µs 15.5 KElem/sec
hnsw_distance_reuse/768d/cosine/control/100           1.00  1940.4±18.93µs  8.1 KElem/sec                1.03   1996.2±8.07µs  7.8 KElem/sec
hnsw_distance_reuse/768d/cosine/control/200           1.00      3.4±0.00ms  4.5 KElem/sec                1.04      3.6±0.03ms  4.4 KElem/sec
hnsw_distance_reuse/768d/cosine/control/50            1.00  1223.9±12.36µs 12.8 KElem/sec                1.03  1261.7±17.84µs 12.4 KElem/sec
hnsw_distance_reuse/768d/dotproduct/candidate/100     1.00  1399.8±13.10µs 11.2 KElem/sec                1.03   1448.2±1.11µs 10.8 KElem/sec
hnsw_distance_reuse/768d/dotproduct/candidate/200     1.00      2.5±0.02ms  6.2 KElem/sec                1.06      2.7±0.03ms  5.9 KElem/sec
hnsw_distance_reuse/768d/dotproduct/candidate/50      1.00    883.9±3.84µs 17.7 KElem/sec                1.04    918.6±0.81µs 17.0 KElem/sec
hnsw_distance_reuse/768d/dotproduct/control/100       1.00   1720.2±3.04µs  9.1 KElem/sec                1.01   1737.0±3.40µs  9.0 KElem/sec
hnsw_distance_reuse/768d/dotproduct/control/200       1.00      3.1±0.00ms  5.0 KElem/sec                1.04      3.2±0.03ms  4.8 KElem/sec
hnsw_distance_reuse/768d/dotproduct/control/50        1.00   1092.0±1.83µs 14.3 KElem/sec                1.01   1100.7±6.27µs 14.2 KElem/sec
hnsw_distance_reuse/768d/euclidean/candidate/100      1.00   1525.4±1.10µs 10.2 KElem/sec                1.04   1581.5±0.84µs  9.9 KElem/sec
hnsw_distance_reuse/768d/euclidean/candidate/200      1.00      2.6±0.00ms  6.0 KElem/sec                1.08      2.8±0.00ms  5.6 KElem/sec
hnsw_distance_reuse/768d/euclidean/candidate/50       1.00   1013.9±4.30µs 15.4 KElem/sec                1.03   1040.2±0.58µs 15.0 KElem/sec
hnsw_distance_reuse/768d/euclidean/control/100        1.00   1936.8±9.48µs  8.1 KElem/sec                1.02   1978.3±1.22µs  7.9 KElem/sec
hnsw_distance_reuse/768d/euclidean/control/200        1.00      3.5±0.02ms  4.5 KElem/sec                1.04      3.6±0.01ms  4.3 KElem/sec
hnsw_distance_reuse/768d/euclidean/control/50         1.00   1250.7±2.71µs 12.5 KElem/sec                1.01   1268.2±1.68µs 12.3 KElem/sec

@github-actions

Copy link
Copy Markdown

Opt-in Benchmark Results: similarity/hnsw_insert_distance_reuse

PR base vs PR branch

group                                                                    main-39939308454-similarity-hnsw_insert_distance_reuse    pr-39939308454-similarity-hnsw_insert_distance_reuse
-----                                                                    ------------------------------------------------------    ----------------------------------------------------
hnsw_insert_distance_reuse/full/128d/cosine/candidate/1000               1.00     62.6±0.40ms 15.6 KElem/sec                       1.05     65.8±1.22ms 14.8 KElem/sec
hnsw_insert_distance_reuse/full/128d/cosine/control/1000                 1.00     74.8±0.60ms 13.1 KElem/sec                       1.00     74.5±1.73ms 13.1 KElem/sec
hnsw_insert_distance_reuse/full/128d/dotproduct/candidate/1000           1.01     60.9±0.27ms 16.0 KElem/sec                       1.00     60.5±0.62ms 16.1 KElem/sec
hnsw_insert_distance_reuse/full/128d/dotproduct/control/1000             1.00     70.0±0.38ms 14.0 KElem/sec                       1.00     69.7±0.50ms 14.0 KElem/sec
hnsw_insert_distance_reuse/full/128d/euclidean/candidate/1000            1.00     61.8±0.64ms 15.8 KElem/sec                       1.03     63.5±0.83ms 15.4 KElem/sec
hnsw_insert_distance_reuse/full/128d/euclidean/control/1000              1.01     73.9±0.76ms 13.2 KElem/sec                       1.00     73.4±0.80ms 13.3 KElem/sec
hnsw_insert_distance_reuse/full/1536d/cosine/candidate/1000              1.01    130.6±1.95ms  7.5 KElem/sec                       1.00    129.0±0.89ms  7.6 KElem/sec
hnsw_insert_distance_reuse/full/1536d/cosine/control/1000                1.00    217.1±3.75ms  4.5 KElem/sec                       1.00    216.6±0.91ms  4.5 KElem/sec
hnsw_insert_distance_reuse/full/1536d/dotproduct/candidate/1000          1.00    124.9±0.44ms  7.8 KElem/sec                       1.01    126.5±0.38ms  7.7 KElem/sec
hnsw_insert_distance_reuse/full/1536d/dotproduct/control/1000            1.00    193.4±0.77ms  5.1 KElem/sec                       1.00    193.3±0.62ms  5.1 KElem/sec
hnsw_insert_distance_reuse/full/1536d/euclidean/candidate/1000           1.00    139.8±0.32ms  7.0 KElem/sec                       1.00    139.8±1.21ms  7.0 KElem/sec
hnsw_insert_distance_reuse/full/1536d/euclidean/control/1000             1.00    227.2±0.38ms  4.3 KElem/sec                       1.02    230.8±5.41ms  4.2 KElem/sec
hnsw_insert_distance_reuse/full/768d/cosine/candidate/1000               1.01    100.0±0.15ms  9.8 KElem/sec                       1.00     99.1±0.71ms  9.9 KElem/sec
hnsw_insert_distance_reuse/full/768d/cosine/control/1000                 1.00    144.0±0.23ms  6.8 KElem/sec                       1.00    143.3±1.03ms  6.8 KElem/sec
hnsw_insert_distance_reuse/full/768d/dotproduct/candidate/1000           1.00     92.8±0.53ms 10.5 KElem/sec                       1.00     92.4±0.67ms 10.6 KElem/sec
hnsw_insert_distance_reuse/full/768d/dotproduct/control/1000             1.02    124.9±2.23ms  7.8 KElem/sec                       1.00    122.9±1.89ms  7.9 KElem/sec
hnsw_insert_distance_reuse/full/768d/euclidean/candidate/1000            1.01    103.6±0.78ms  9.4 KElem/sec                       1.00    102.6±0.93ms  9.5 KElem/sec
hnsw_insert_distance_reuse/full/768d/euclidean/control/1000              1.00    142.0±1.21ms  6.9 KElem/sec                       1.02    144.8±3.55ms  6.7 KElem/sec
hnsw_insert_distance_reuse/incremental/128d/cosine/candidate/100         1.00     11.8±0.08ms  8.3 KElem/sec                       1.01     11.9±0.10ms  8.2 KElem/sec
hnsw_insert_distance_reuse/incremental/128d/cosine/control/100           1.01     13.4±0.14ms  7.3 KElem/sec                       1.00     13.3±0.15ms  7.3 KElem/sec
hnsw_insert_distance_reuse/incremental/128d/dotproduct/candidate/100     1.01     12.0±0.14ms  8.2 KElem/sec                       1.00     11.9±0.09ms  8.2 KElem/sec
hnsw_insert_distance_reuse/incremental/128d/dotproduct/control/100       1.01     13.0±0.16ms  7.5 KElem/sec                       1.00     12.9±0.15ms  7.6 KElem/sec
hnsw_insert_distance_reuse/incremental/128d/euclidean/candidate/100      1.00     11.2±0.10ms  8.7 KElem/sec                       1.02     11.4±0.15ms  8.6 KElem/sec
hnsw_insert_distance_reuse/incremental/128d/euclidean/control/100        1.00     12.4±0.15ms  7.8 KElem/sec                       1.02     12.7±0.31ms  7.7 KElem/sec
hnsw_insert_distance_reuse/incremental/1536d/cosine/candidate/100        1.00     18.5±0.02ms  5.3 KElem/sec                       1.02     18.8±0.19ms  5.2 KElem/sec
hnsw_insert_distance_reuse/incremental/1536d/cosine/control/100          1.00     28.1±0.11ms  3.5 KElem/sec                       1.01     28.4±0.34ms  3.4 KElem/sec
hnsw_insert_distance_reuse/incremental/1536d/dotproduct/candidate/100    1.00     20.2±0.47ms  4.8 KElem/sec                       1.00     20.2±0.41ms  4.8 KElem/sec
hnsw_insert_distance_reuse/incremental/1536d/dotproduct/control/100      1.00     27.4±0.29ms  3.6 KElem/sec                       1.00     27.4±0.08ms  3.6 KElem/sec
hnsw_insert_distance_reuse/incremental/1536d/euclidean/candidate/100     1.02     19.3±0.07ms  5.1 KElem/sec                       1.00     19.0±0.09ms  5.1 KElem/sec
hnsw_insert_distance_reuse/incremental/1536d/euclidean/control/100       1.02     29.7±0.03ms  3.3 KElem/sec                       1.00     29.1±0.39ms  3.4 KElem/sec
hnsw_insert_distance_reuse/incremental/768d/cosine/candidate/100         1.03     15.4±0.12ms  6.3 KElem/sec                       1.00     15.0±0.18ms  6.5 KElem/sec
hnsw_insert_distance_reuse/incremental/768d/cosine/control/100           1.03     20.5±0.32ms  4.8 KElem/sec                       1.00     19.8±0.32ms  4.9 KElem/sec
hnsw_insert_distance_reuse/incremental/768d/dotproduct/candidate/100     1.00     15.9±0.14ms  6.2 KElem/sec                       1.00     15.9±0.07ms  6.1 KElem/sec
hnsw_insert_distance_reuse/incremental/768d/dotproduct/control/100       1.00     19.1±0.22ms  5.1 KElem/sec                       1.01     19.3±0.18ms  5.1 KElem/sec
hnsw_insert_distance_reuse/incremental/768d/euclidean/candidate/100      1.01     15.1±0.05ms  6.5 KElem/sec                       1.00     15.0±0.09ms  6.5 KElem/sec
hnsw_insert_distance_reuse/incremental/768d/euclidean/control/100        1.02     19.6±0.08ms  5.0 KElem/sec                       1.00     19.3±0.11ms  5.1 KElem/sec

@jimezesinachi
jimezesinachi merged commit 4334452 into main Oct 23, 2026
8 checks passed
@jimezesinachi
jimezesinachi deleted the perf/hnsw-compact-adjacency branch October 23, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

benchmark-experiments Trigger opt-in Criterion benchmark comparisons

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants