A Rust-backed, pandas-shaped DataFrame for live
OHLCV pipelines: a broad trading-indicator set, incremental O(lookback)
refresh on each new bar, and NumPy/Torch-ready output. This page is the
project's reproducible benchmark report — regenerated from
make benchmark on each release. See the
repository for docs and
installation.On this run, volas beats TA-Lib on 150 / 158 covered indicators by the default ratio, using the full coverage table below.
Benchmark report
OHLCV technical-indicator computation across libraries ·
2026-09-07T10:56:47.508964+00:00 · Apple M1 (Virtual) · Python 3.12.10
Lower time is better; Perf shows the slowest candidate as
1.00× and each faster candidate as {slowest ÷ this}×.
The live loop: fold a new 1-minute bar into a 15-minute series and refresh atr:14 over a bounded 30-bar window, every bar, for 20 000 bars. volas does this natively (a windowed, tf-aware frame that auto-compacts, so memory stays O(window + lookback)); the other libraries have no such primitive, so each is given a hand-written, non-lazy equivalent — a trimmed ring of the last window + max_lookback 15-minute bars, folded the same way and re-run through that library's ATR (never an O(n) recompute over all history). Times are per bar, amortized over the 20 000-bar stream (so volas's periodic compaction is included).
atr:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
633.9 ns
631.8 ns
1,577,608
3
67.18×
talib
6.15 µs
6.15 µs
162,620
3
6.90×
polars
33.92 µs
33.92 µs
29,482
3
1.25×
pandas
43.22 µs
42.45 µs
23,135
3
1.00×
Append one new bar → updated indicator
A new bar arrives. volas / stock_pandas refresh their cached column incrementally (O(lookback)); the libraries with no indicator cache (pandas / pandas_ta / polars / talib) must recompute the series (O(n)). Every candidate is measured with the same round count so the rounds column is comparable.
The data-handling plumbing a live system runs around every indicator call — frame construction, column access, row slicing, boolean masking, column assignment, copy — timed against pandas / polars. Not indicator math; the surrounding core APIs.
construct
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.16 µs
4.42 µs
193,965
30038
12.57×
polars
29.04 µs
23.33 µs
34,430
832
2.38×
pandas
65.13 µs
55.50 µs
15,353
640
1.00×
copy
Candidate
Mean
Median
OPS
rounds
Perf
volas
302.1 ns
292.0 ns
3,310,473
42856
102.74×
polars
408.7 ns
375.0 ns
2,446,593
2743
80.00×
pandas
31.73 µs
30.00 µs
31,517
4029
1.00×
getcol
Candidate
Mean
Median
OPS
rounds
Perf
volas
401.9 ns
333.0 ns
2,488,015
27778
21.52×
polars
728.1 ns
542.0 ns
1,373,441
8612
13.22×
pandas
8.34 µs
7.17 µs
119,908
933
1.00×
mask
Candidate
Mean
Median
OPS
rounds
Perf
volas
11.17 µs
10.29 µs
89,525
17455
6.68×
polars
60.96 µs
52.35 µs
16,404
82
1.31×
pandas
70.95 µs
68.71 µs
14,094
532
1.00×
setitem
Candidate
Mean
Median
OPS
rounds
Perf
volas
1.22 µs
1.21 µs
822,232
2769
12.11×
pandas
10.39 µs
8.04 µs
96,287
1772
1.82×
polars
16.93 µs
14.62 µs
59,079
404
1.00×
slice
Candidate
Mean
Median
OPS
rounds
Perf
polars
3.91 µs
2.21 µs
255,779
414
2.32×
volas
2.86 µs
2.46 µs
350,013
1142
2.08×
pandas
6.22 µs
5.13 µs
160,771
8357
1.00×
Batch indicator computation
Compute the indicator over the whole series, across every library.
atr:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.87 µs
4.33 µs
170,465
14617
112.78×
talib
17.49 µs
14.58 µs
57,184
29740
33.51×
polars
126.99 µs
91.17 µs
7,875
2588
5.36×
stock_pandas
102.24 µs
97.46 µs
9,781
4826
5.02×
pandas_ta
114.96 µs
111.58 µs
8,699
3206
4.38×
pandas
505.52 µs
488.77 µs
1,978
908
1.00×
boll.upper
Candidate
Mean
Median
OPS
rounds
Perf
volas
6.17 µs
6.08 µs
161,968
35191
71.85×
talib
12.09 µs
11.92 µs
82,705
33013
36.68×
polars
92.84 µs
90.75 µs
10,771
3236
4.82×
pandas
156.01 µs
152.54 µs
6,410
1931
2.87×
stock_pandas
164.92 µs
162.38 µs
6,064
2925
2.69×
pandas_ta
454.00 µs
437.08 µs
2,203
919
1.00×
ema:12
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.27 µs
5.21 µs
189,863
56603
10.29×
talib
7.07 µs
6.96 µs
141,423
42180
7.70×
stock_pandas
42.61 µs
38.25 µs
23,467
8572
1.40×
polars
42.66 µs
39.21 µs
23,442
5217
1.37×
pandas
43.50 µs
41.54 µs
22,989
3433
1.29×
pandas_ta
55.87 µs
53.58 µs
17,899
4472
1.00×
hhv:10
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.05 µs
3.21 µs
198,074
20762
22.33×
talib
8.06 µs
5.75 µs
124,057
19418
12.46×
polars
40.96 µs
31.08 µs
24,417
3641
2.30×
stock_pandas
72.14 µs
51.75 µs
13,862
5953
1.38×
pandas
110.00 µs
71.62 µs
9,091
2123
1.00×
llv:10
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.06 µs
3.87 µs
197,738
24845
21.70×
talib
8.54 µs
6.04 µs
117,075
16878
13.92×
polars
49.54 µs
37.94 µs
20,187
1126
2.22×
stock_pandas
89.75 µs
62.38 µs
11,143
1471
1.35×
pandas
130.39 µs
84.08 µs
7,669
1082
1.00×
ma:20
Candidate
Mean
Median
OPS
rounds
Perf
volas
4.51 µs
4.42 µs
221,843
42106
15.23×
talib
6.94 µs
6.21 µs
144,192
42404
10.83×
polars
35.16 µs
33.25 µs
28,443
4951
2.02×
pandas
48.54 µs
45.33 µs
20,602
3173
1.48×
pandas_ta
57.01 µs
53.08 µs
17,541
4394
1.27×
stock_pandas
71.80 µs
67.25 µs
13,927
6757
1.00×
macd
Candidate
Mean
Median
OPS
rounds
Perf
volas
7.06 µs
6.96 µs
141,594
40817
39.71×
talib
18.19 µs
17.92 µs
54,972
22902
15.43×
stock_pandas
51.93 µs
50.67 µs
19,258
8103
5.45×
polars
433.45 µs
76.21 µs
2,307
4210
3.63×
pandas
95.17 µs
92.04 µs
10,507
2737
3.00×
pandas_ta
290.46 µs
276.37 µs
3,443
1459
1.00×
macd.signal
Candidate
Mean
Median
OPS
rounds
Perf
volas
12.24 µs
11.75 µs
81,709
40202
1705.18×
talib
18.20 µs
17.96 µs
54,950
12800
1115.64×
stock_pandas
63.71 µs
62.00 µs
15,696
5993
323.16×
pandas
128.92 µs
125.15 µs
7,757
2464
160.10×
pandas_ta
285.55 µs
274.25 µs
3,502
1395
73.06×
polars
15.37 ms
20.04 ms
65
96
1.00×
rsi:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
12.27 µs
12.08 µs
81,515
39669
38.20×
talib
14.36 µs
14.13 µs
69,621
34683
32.68×
stock_pandas
61.05 µs
58.21 µs
16,380
5486
7.93×
pandas_ta
67.96 µs
63.67 µs
14,715
3096
7.25×
polars
170.40 µs
164.08 µs
5,868
1709
2.81×
pandas
509.60 µs
461.62 µs
1,962
929
1.00×
willr:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
10.01 µs
9.87 µs
99,865
22621
22.24×
talib
11.93 µs
11.75 µs
83,854
26374
18.69×
pandas_ta
89.54 µs
85.83 µs
11,169
3164
2.56×
polars
702.50 µs
96.96 µs
1,423
2972
2.27×
pandas
228.31 µs
219.62 µs
4,380
1523
1.00×
Full coverage — volas vs TA-Lib
Every indicator both volas and TA-Lib implement (the set the parity suite aligns), one row per indicator. The default volas vs TA-Lib column is the Tencent fixture; optional generated lengths and cached append refresh appear as additional ratio columns. Values > 1.00× mean volas is faster.
volas beats TA-Lib on 150 / 158 covered indicators by the default ratio (0 exactly even, 8 slower).