Seurat FindNeighbors is one of the slower steps in many single-cell genomics workflows. AutoZyme ships a
verified, drop-in patch that is up to 4.23× faster, returning bit-for-bit identical results with no change to how you call it.
Best speedup4.23×
Median speedup3.25×
Output equivalenceBit-exact
Best runtime baseline 20.10 s → optimized 5.59 s
Datasets7
Pass rate11/11
Benchmark charts
Switch benchmark platform; all charts update together
Platform
Speedup distribution
Each dot is one finalized dataset/thread run on Windows
tms_ss2
tms_ss2 · ood_large21 threads · 1.25× speedup23.67 s baseline → 18.98 s optimizedmemory 24 GB → 24 GBtms_ss2 · ood_large24 threads · 2.53× speedup26.85 s baseline → 9.36 s optimizedmemory 24 GB → 24 GBtms_ss2 · ood_large232 threads · 4.23× speedup20.10 s baseline → 5.59 s optimizedmemory 24 GB → 24 GB
4.23×
splitseq_rosenberg
splitseq_rosenberg · ood_large11 threads · 1.18× speedup33.27 s baseline → 28.17 s optimizedmemory 21 GB → 14 GBsplitseq_rosenberg · ood_large14 threads · 2.65× speedup33.08 s baseline → 12.54 s optimizedmemory 21 GB → 14 GBsplitseq_rosenberg · ood_large132 threads · 3.62× speedup33.40 s baseline → 9.20 s optimizedmemory 21 GB → 14 GB
3.62×
heart_adult
heart_adult · large1 threads · 1.15× speedup1.85 min baseline → 1.60 min optimizedmemory 73 GB → 52 GBheart_adult · large4 threads · 2.34× speedup1.83 min baseline → 46.87 s optimizedmemory 73 GB → 52 GBheart_adult · large32 threads · 3.43× speedup1.83 min baseline → 31.99 s optimizedmemory 73 GB → 52 GB
3.43×
gastrulation_pijuansa…
gastrulation_pijuansala · ood_large31 threads · 1.11× speedup25.78 s baseline → 22.36 s optimizedmemory 41 GB → 37 GBgastrulation_pijuansala · ood_large34 threads · 2.32× speedup24.65 s baseline → 10.64 s optimizedmemory 41 GB → 37 GBgastrulation_pijuansala · ood_large332 threads · 3.38× speedup24.72 s baseline → 7.32 s optimizedmemory 41 GB → 37 GB
3.38×
pbmc68k
pbmc68k · small1 threads · 1.14× speedup14.30 s baseline → 13.77 s optimizedmemory 7.3 GB → 5.3 GBpbmc68k · small4 threads · 2.57× speedup16.38 s baseline → 6.09 s optimizedmemory 7.3 GB → 5.3 GBpbmc68k · small32 threads · 3.33× speedup15.67 s baseline → 4.70 s optimizedmemory 7.3 GB → 5.3 GB
3.33×
pbmc200k_glaucoma
pbmc200k_glaucoma · medium1 threads · 1.17× speedup44.65 s baseline → 38.25 s optimizedmemory 29 GB → 20 GBpbmc200k_glaucoma · medium4 threads · 2.00× speedup43.88 s baseline → 22.37 s optimizedmemory 29 GB → 20 GBpbmc200k_glaucoma · medium32 threads · 3.13× speedup56.81 s baseline → 14.27 s optimizedmemory 29 GB → 20 GB
The public API stays the same; AutoZyme replaces only the supported fast path.
This task targets FindNeighbors in Seurat. The benchmarked result
preserves the declared scientific output gate while reducing CPU runtime on the listed datasets.
Fast path is taken only for: a Seurat object (inherits "Seurat"), nn.method == "annoy", annoy.metric == "euclidean", return.neighbor == FALSE, l2.norm == FALSE, and the zyme flag TRUE (lines 373-376).Read full supported scope
Fast path is taken only for: a Seurat object (inherits "Seurat"), nn.method == "annoy", annoy.metric == "euclidean", return.neighbor == FALSE, l2.norm == FALSE, and the zyme flag TRUE (lines 373-376). On that path it builds an Annoy Euclidean index from Embeddings(object[[reduction]])[, dims] in C++ (single-threaded build, std::thread-parallel k-NN search over OMP_NUM_THREADS / detectCores), then constructs the NN sparse Graph and, when compute.SNN is TRUE, the SNN graph via Seurat:::ComputeSNN(prune = prune.SNN). Correctly honored args: reduction (any reduction present in the object), dims (any column subset that exists), k.param, n.trees, prune.SNN, compute.SNN, graph.name, verbose. Equivalence is approximate-only: the metric is knn_jaccard >= 0.85, not bit-exact (Annoy is approximate and the kernel casts to float32). This covers the benchmarked default Annoy/Euclidean graph configuration.
Out-of-scope behavior
silent fallback to upstream
Show detailed speedup table11 runs▾
Dataset
Tier
Platform
Threads
Baseline
Optimized
Speedup
Memory
Concordance
Pass
gastrulation_pijuansala
ood_large3
Windows
32
24.72 s
7.32 s
3.38×
40.6 → 37.1 GB
—
pass
heart_adult
large
Windows
32
1.83 min
31.99 s
3.43×
73.5 → 52.1 GB
—
pass
pbmc200k_glaucoma
medium
Windows
32
56.81 s
14.27 s
3.13×
28.7 → 20.2 GB
—
pass
pbmc68k
small
Windows
32
15.67 s
4.70 s
3.33×
7.3 → 5.3 GB
—
pass
splitseq_rosenberg
ood_large1
Windows
32
33.40 s
9.20 s
3.62×
20.5 → 14.2 GB
—
pass
tms_ss2
ood_large2
Windows
32
20.10 s
5.59 s
4.23×
24.1 → 23.8 GB
—
pass
gastrulation_pijuansala
ood_large3
macOS
14
19.94 s
6.35 s
3.13×
14.4 → 14.0 GB
—
pass
pbmc200k_glaucoma
medium
macOS
14
34.08 s
10.62 s
3.21×
10.0 → 9.5 GB
—
pass
pbmc68k (inferred)
small
macOS
14
14.07 s
4.44 s
3.17×
15.3 → 10.3 GB
—
pass
splitseq_rosenberg
ood_large1
macOS
14
25.17 s
7.75 s
3.25×
6.4 → 6.2 GB
—
pass
tms_ss2
ood_large2
macOS
14
16.14 s
5.09 s
3.15×
9.0 → 8.7 GB
—
pass
Frequently asked questions
Speeding up Seurat FindNeighbors
Why is Seurat FindNeighbors slow?
Seurat FindNeighbors is CPU-bound, and the stock implementation in Seurat leaves performance on the table in its core numerical work. On the benchmark datasets the original takes 20.10 s where the AutoZyme path takes 5.59 s (4.23× faster).
How do I make Seurat FindNeighbors faster?
Install AutoZyme and activate the Seurat patch, then keep using Seurat FindNeighbors exactly as before. AutoZyme transparently substitutes the faster, output-validated path, up to 4.23× faster on the benchmark datasets, with no pipeline or API changes.
Does the AutoZyme speedup change the Seurat FindNeighbors output?
No. The accelerated path returns bit-for-bit identical results to the original Seurat implementation (maximum absolute difference 0), checked by a frozen concordance gate on every benchmark dataset.
How do I install the Seurat speedup?
In R: install the autozyme package, then run library(autozyme) and autozyme::activate("seurat"). The patch applies automatically the next time you call FindNeighbors.