R Seurat methods Seurat

Speed up Seurat FindNeighbors

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 speedup 4.23×
Median speedup 3.25×
Output equivalence Bit-exact
Best runtime baseline 20.10 s optimized 5.59 s
Datasets 7
Pass rate 11/11

Benchmark charts

Switch benchmark platform; all charts update together
Platform
Speedup distribution
Each dot is one finalized dataset/thread run on Windows
tms_ss2splitseq_rosenbergheart_adultgastrulation_pijuansa…pbmc68kpbmc200k_glaucoma
Thread sweep
Speedup across finalized thread counts on Windows
2.5×14full (32)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 GBsplitseq_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 GBheart_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 GBgastrulation_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 GBpbmc68k · 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 GBpbmc200k_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
tms_ss2splitseq_rosenbergheart_adultgastrulation_pijuan…pbmc68kpbmc200k_glaucoma
Memory
Baseline vs optimized peak memory on Windows
0.0 GB50 GB100 GBheart_adult0.71×gastrulation_piju…0.91×pbmc200k_glaucoma0.70×tms_ss20.99×splitseq_rosenberg0.69×pbmc68k0.73×heart_adult · largememory 73 GB → 52 GBoptimized / baseline 0.71×3.43× speedup · 32 threadsgastrulation_pijuansala · ood_large3memory 41 GB → 37 GBoptimized / baseline 0.91×3.38× speedup · 32 threadspbmc200k_glaucoma · mediummemory 29 GB → 20 GBoptimized / baseline 0.70×3.13× speedup · 32 threadstms_ss2 · ood_large2memory 24 GB → 24 GBoptimized / baseline 0.99×4.23× speedup · 32 threadssplitseq_rosenberg · ood_large1memory 21 GB → 14 GBoptimized / baseline 0.69×3.62× speedup · 32 threadspbmc68k · smallmemory 7.3 GB → 5.3 GBoptimized / baseline 0.73×3.33× speedup · 32 threads
baselineoptimized

What is accelerated

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.

Also searched as: KNN, kNN graph, nearest neighbors, SNN, shared nearest neighbor, neighborhood graph.

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). 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 table 11 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.