A high-performance algorithm library built in Rust for Python.
Project description
algofarm
Fast, dependency-free algorithms for Python, implemented from scratch in Rust.
No rand, no rayon, no std::collections::HashMap under the hood — just pyo3 and
hand-rolled implementations of the things people rewrite in every project: sorting,
searching, string distance, number theory, basic stats, and a custom hashmap you can
use directly from Python.
Why
Python's standard library and numpy already cover a lot of this, but:
sorted(x)[:k]sorts the whole array to get the topk—top_kdoesn't.- Pure-Python Levenshtein distance is slow enough to matter on real string data.
list(dict.fromkeys(x))for dedup pays per-element interpreter overhead at scale.- Everyone has a copy-pasted GCD/sieve/Miller-Rabin snippet from an old competitive programming folder.
algofarm exists so you don't have to write (or copy-paste) these again.
Install
pip install maturin
maturin develop --release
This builds the Rust extension and installs it into your active Python environment.
Use --release — debug builds of the sort/search functions are dramatically slower.
Sorting
import algofarm
algofarm.quicksort([5, 3, 8, 1]) # [1, 3, 5, 8] — randomized pivot, 3-way partition
algofarm.quicksort_f64([3.1, 1.5, 2.2]) # float variant, NaN-safe ordering
algofarm.mergesort([5, 3, 8, 1]) # stable, O(n log n) guaranteed
algofarm.parallel_sort(big_list) # multi-threaded via std::thread; only worth it above ~50k elements
quicksort uses a randomized pivot and Dutch-flag 3-way partitioning, so duplicate-heavy
data and adversarial inputs don't degrade to O(n²). Recursion always descends into the
smaller partition first, which bounds stack depth to O(log n) regardless of input shape.
Arrays of 16 or fewer elements fall back to insertion sort.
Searching
algofarm.binary_search([1, 3, 5, 7, 9], 5) # 2 (index), or None if not found
algofarm.kth_smallest([9, 2, 7, 4, 1], 2) # 2nd smallest, O(n) average — no full sort
algofarm.top_k([9, 2, 7, 4, 1], 3) # [9, 7, 4], descending
kth_smallest and top_k use quickselect, so pulling the top 100 rows out of 50 million
doesn't pay for sorting the other 49,999,900.
Deduplication
algofarm.dedup([1, 2, 2, 3, 1, 4]) # [1, 2, 3, 4] — first-occurrence order preserved
String distance
algofarm.levenshtein("kitten", "sitting") # 3
Rolling two-row DP — O(min(n, m)) space instead of the full O(n·m) matrix.
Number theory
algofarm.gcd(48, 18) # 6
algofarm.lcm(4, 6) # 12
algofarm.mod_pow(7, 128, 13) # binary exponentiation, u128 intermediate — no overflow
algofarm.is_prime(982451653) # deterministic Miller-Rabin, correct for the full u64 range
algofarm.sieve(100) # all primes up to 100, as a list
algofarm.fibonacci(50) # fast doubling, O(log n) — not the naive O(n) loop
Statistics
algofarm.mean([1.0, 2.0, 3.0]) # 2.0
algofarm.median([1.0, 2.0, 3.0]) # 2.0
algofarm.variance([1.0, 2.0, 3.0]) # population variance (divides by n, not n-1)
algofarm.std_dev([1.0, 2.0, 3.0])
Linear algebra
algofarm.dot_product([1.0, 2.0], [3.0, 4.0]) # 11.0
algofarm.matmul(a, b) # a: m×k, b: k×n -> m×n; raises ValueError on mismatch
matmul uses i-k-j loop ordering for cache locality and skips multiplies against zero
entries — meaningfully faster than the naive i-j-k triple loop on anything but tiny matrices.
FarmHashMap
A hand-rolled open-addressing hashmap (linear probing, tombstone deletion, grows at 70% load factor), usable as a Python object:
from algofarm import FarmHashMap
m = FarmHashMap()
m.insert(1, 100)
m.get(1) # 100
m.contains(1) # True
m.remove(1) # 100 (the removed value)
len(m)
m.keys()
m.values()
m.items()
Currently keyed on int -> int. Hashing is a splitmix64-style bit mixer, not
std::collections::HashMap's default hasher.
Performance notes
parallel_sortspawns real OS threads viastd::thread::scopeand only pays that overhead above ~50,000 elements — below that it silently falls back to the sequentialquicksort.- All functions release the GIL during the actual computation (
py.allow_threads), so other Python threads keep running while algofarm works — this matters if you're calling these from a multi-threaded application, not just for the parallel_sort case. is_primeis deterministic (not probabilistic) for the entireu64range using a fixed 12-witness Miller-Rabin set — no false positives, unlike a naive random-witness version.
Testing
Correctness is checked against Python's standard library and reference implementations
across randomized inputs (fixed seed for reproducibility) — sorting against sorted(),
number theory against math/trial division, stats against the statistics module,
FarmHashMap against dict under randomized insert/get/remove/contains sequences.
Design philosophy
Zero dependencies beyond pyo3. No rand, no rayon, no std::collections::HashMap.
Randomization uses a hand-rolled xorshift64* PRNG; parallelism uses raw std::thread;
the hashmap is open-addressing from scratch. The point isn't that these beat a
well-optimized crate on every benchmark — it's that nothing in this library is a black
box you have to trust without being able to read it in five minutes.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file algofarm-0.1.1-cp312-abi3-win_amd64.whl.
File metadata
- Download URL: algofarm-0.1.1-cp312-abi3-win_amd64.whl
- Upload date:
- Size: 171.2 kB
- Tags: CPython 3.12+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a70c81880fdbc33a0612ff647742cdbf94e60713d63a935b9c1cc19d12941944
|
|
| MD5 |
aaa77f8face86a3e0a89a8bef72418ea
|
|
| BLAKE2b-256 |
8403c62685475d6ace9e3afaf195e4a86ebd7fce44b87a3912b5d661d400769b
|
File details
Details for the file algofarm-0.1.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: algofarm-0.1.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 325.9 kB
- Tags: CPython 3.12+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3486090cd3cce7cdfc2dc506d42b7bdbd0f886e2713f75f1591538d2fc9c9eb
|
|
| MD5 |
7a972559cf889c6a65858c38f72979d4
|
|
| BLAKE2b-256 |
f5e472dc7efc156e7b2f9392e288950ee78d89bfac56a88704427f3cc4f569ed
|
File details
Details for the file algofarm-0.1.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: algofarm-0.1.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 324.1 kB
- Tags: CPython 3.12+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b16c31373fc597e6914cba22d74e3ae0e503c1f472e4a473501919b14c62262
|
|
| MD5 |
378970b9555117d0b139ad9a9de6e50b
|
|
| BLAKE2b-256 |
0740348f1bf4ad78d0870b0ed423aeb6d42d3ff8cd49aa600d2e9a621e61b95b
|
File details
Details for the file algofarm-0.1.1-cp312-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: algofarm-0.1.1-cp312-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 282.0 kB
- Tags: CPython 3.12+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ff2eb281780f0f1c387506ab5fd63572015ff726989dc4bf0f3fd837ffb5b40
|
|
| MD5 |
0aeb0004f08a46a5f9a7c78a8b8392dd
|
|
| BLAKE2b-256 |
8fbd4a53d8cf24554de283a1d29c484932b9de90057143a929e67108d8845d9e
|
File details
Details for the file algofarm-0.1.1-cp312-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: algofarm-0.1.1-cp312-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 284.0 kB
- Tags: CPython 3.12+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7abc536e6f8d6ead9724a4e62e156938dada8ebaa5da1db1b6644875686c6b5f
|
|
| MD5 |
0120cc67f7a150e973824b8131a24aa0
|
|
| BLAKE2b-256 |
28a19a2d778fbc2102b9e566c8ace53f91a9c27d29337ae22f081b41c46bc760
|