Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Performance vs scikit-learn

The numbers below are measured, not estimated. The same deterministic synthetic dataset (xorshift64, seed 42, values in [-100, 100)) is fed to both libraries, and the median fit_transform time over 15 runs (after one warmup) is reported.

Test setup: Apple M5 Pro (18 cores, arm64), Rust 1.96.0 (release), Python 3.9.6, scikit-learn 1.6.1, numpy 2.0.2, scipy 1.13.1. Times are in milliseconds. The Ratio column is sklearn_ms / datarust_ms — values > 1 mean datarust is faster.

Benchmark table

WorkloadSize (rows × cols)datarust default (ms)datarust +rayon (ms)sklearn (ms)best ratio
StandardScaler1 000 × 100.0230.0160.28017.5×
StandardScaler10 000 × 1001.241.202.462.0×
StandardScaler50 000 × 2008.24.722.44.8×
MinMaxScaler1 000 × 100.0250.0140.20214.4×
MinMaxScaler10 000 × 1001.701.471.320.9×
MinMaxScaler50 000 × 20010.87.511.61.5×
RobustScaler1 000 × 100.170.130.7685.8×
RobustScaler10 000 × 10011.22.0921.410×
RobustScaler50 000 × 20012314.0193.513.8×
PCA (k = min(10, cols/2))1 000 × 100.180.100.2262.2×
PCA10 000 × 10045411.390.03×
PCA50 000 × 20083881912.20.01×
Pipeline (Standard→MinMax→Robust)1 000 × 100.200.211.024.9×
Pipeline10 000 × 10013.24.125.26.1×
Pipeline50 000 × 20014426.7229.68.6×
OneHotEncoder (string)1 000 × 50.380.550.8001.5×
OneHotEncoder10 000 × 107.46.89.91.5×
OneHotEncoder50 000 × 2089802052.6×
ColumnTransformer (num + cat)1 000 × 50.0260.0264.6179×
ColumnTransformer10 000 × 100.230.2479.8347×
ColumnTransformer50 000 × 201.311.32812.8620×
LinearRegression (fit+predict)1 000 × 100.160.16
LinearRegression10 000 × 10014.414.4
LinearRegression50 000 × 200258258

Feature flags make a difference

matrixmultiply. Enabling this feature dispatches covariance and matmuls to a tuned pure-Rust GEMM (no system BLAS). On 50 000 × 200, PCA drops from 838 ms → 104 ms (8× faster), and LinearRegression from 258 ms → 84 ms (3× faster).

rayon. Parallel column/row processing. RobustScaler at 50 000 × 200 drops from 123 ms (default) to 14 ms (8.8× faster with rayon).

Where datarust wins

  • Mixed numeric + categorical composition. ColumnTransformer is 179–620× faster than scikit-learn’s on large inputs. This is the headline result — it reflects the cost of sklearn’s per-column Python dispatch, dtype coercion, and object-array marshalling.
  • String / categorical encoding. OneHotEncoder is ~1.5–2.6× faster because datarust operates on a native StrMatrix directly — no Python object-array overhead, no GIL.
  • Numeric scalers with rayon. StandardScaler/RobustScaler/Pipeline beat sklearn by 4.8–13.8× at 50 000 × 200.
  • Small data and startup latency. At 1 000 × 10, datarust is faster on every workload — up to 17.5× on StandardScaler. No Python interpreter to spin up, no numpy import cost.

Where scikit-learn still wins

  • PCA on tall-and-wide data (without the matrixmultiply feature). sklearn calls into LAPACK’s full SVD via shared-library BLAS; datarust uses a from-scratch Jacobi sweep. With matrixmultiply the gap narrows from 85× to ~8×, and PCASolver::Randomized closes it further for low-rank inputs.

Reproduce the benchmarks

The harness lives in examples/bench_compare_rust.rs (Rust side) and benches/compare_sklearn.py (Python side). Run on your own hardware:

# Rust (all feature combos)
cargo run --release --features matrixmultiply --example bench_compare_rust 15

# Python (requires numpy, scikit-learn)
python3 benches/compare_sklearn.py 15