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 151 / 158 covered indicators by the default ratio, using the full coverage table below.
Benchmark report
OHLCV technical-indicator computation across libraries ·
2026-10-05T12:54:53.556454+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
1.03 µs
1.12 µs
968,733
3
65.24×
talib
8.40 µs
8.30 µs
119,013
3
8.78×
polars
66.25 µs
63.39 µs
15,095
3
1.15×
pandas
72.14 µs
72.92 µs
13,861
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
4.44 µs
4.29 µs
225,176
34633
11.91×
polars
23.37 µs
22.50 µs
42,781
913
2.27×
pandas
54.11 µs
51.13 µs
18,480
274
1.00×
copy
Candidate
Mean
Median
OPS
rounds
Perf
volas
392.9 ns
333.0 ns
2,544,910
24666
94.22×
polars
391.9 ns
375.0 ns
2,551,903
2043
83.67×
pandas
149.02 µs
31.37 µs
6,711
3792
1.00×
getcol
Candidate
Mean
Median
OPS
rounds
Perf
volas
335.9 ns
333.0 ns
2,977,093
58824
21.15×
polars
471.1 ns
458.0 ns
2,122,566
5137
15.38×
pandas
7.60 µs
7.04 µs
131,650
658
1.00×
mask
Candidate
Mean
Median
OPS
rounds
Perf
volas
11.38 µs
10.50 µs
87,844
1855
13.84×
pandas
98.18 µs
79.83 µs
10,185
317
1.82×
polars
155.75 µs
145.33 µs
6,420
75
1.00×
setitem
Candidate
Mean
Median
OPS
rounds
Perf
volas
1.15 µs
1.13 µs
869,972
2196
12.22×
pandas
8.23 µs
7.92 µs
121,450
1374
1.74×
polars
14.23 µs
13.75 µs
70,287
492
1.00×
slice
Candidate
Mean
Median
OPS
rounds
Perf
volas
3.50 µs
2.62 µs
286,082
8606
2.05×
pandas
7.80 µs
5.08 µs
128,186
3225
1.06×
polars
7.29 µs
5.38 µs
137,169
66
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.39 µs
4.50 µs
185,692
37325
138.79×
talib
18.74 µs
14.83 µs
53,368
30929
42.10×
stock_pandas
143.76 µs
105.75 µs
6,956
2782
5.91×
polars
214.89 µs
117.02 µs
4,654
1956
5.34×
pandas_ta
140.01 µs
120.71 µs
7,142
2253
5.17×
pandas
642.77 µs
624.54 µs
1,556
508
1.00×
boll.upper
Candidate
Mean
Median
OPS
rounds
Perf
volas
7.48 µs
6.17 µs
133,652
23646
99.44×
talib
13.98 µs
12.00 µs
71,544
35928
51.10×
polars
304.31 µs
93.46 µs
3,286
1818
6.56×
pandas
233.74 µs
182.88 µs
4,278
1195
3.35×
stock_pandas
224.88 µs
183.04 µs
4,447
3303
3.35×
pandas_ta
788.01 µs
613.15 µs
1,269
658
1.00×
ema:12
Candidate
Mean
Median
OPS
rounds
Perf
volas
10.65 µs
5.21 µs
93,927
24845
13.57×
talib
8.68 µs
7.00 µs
115,187
31704
10.10×
stock_pandas
58.30 µs
40.42 µs
17,153
7493
1.75×
pandas
67.02 µs
45.75 µs
14,920
3129
1.55×
polars
66.84 µs
47.83 µs
14,960
6013
1.48×
pandas_ta
100.44 µs
70.71 µs
9,956
1118
1.00×
hhv:10
Candidate
Mean
Median
OPS
rounds
Perf
volas
3.73 µs
3.21 µs
268,128
36037
17.67×
talib
7.40 µs
5.83 µs
135,172
30001
9.72×
polars
39.43 µs
30.04 µs
25,362
5903
1.89×
stock_pandas
61.34 µs
51.37 µs
16,302
5309
1.10×
pandas
68.99 µs
56.71 µs
14,496
2870
1.00×
llv:10
Candidate
Mean
Median
OPS
rounds
Perf
volas
4.50 µs
3.83 µs
221,999
41959
19.86×
talib
6.65 µs
5.83 µs
150,350
25210
13.05×
polars
48.31 µs
35.62 µs
20,699
3925
2.14×
stock_pandas
82.00 µs
51.63 µs
12,196
3104
1.47×
pandas
99.38 µs
76.15 µs
10,063
1880
1.00×
ma:20
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.58 µs
4.42 µs
179,194
13606
18.04×
talib
9.72 µs
6.25 µs
102,861
28236
12.75×
polars
64.34 µs
40.25 µs
15,544
5153
1.98×
pandas
97.74 µs
57.58 µs
10,231
2587
1.38×
pandas_ta
93.92 µs
64.79 µs
10,647
2958
1.23×
stock_pandas
128.87 µs
79.67 µs
7,760
4575
1.00×
macd
Candidate
Mean
Median
OPS
rounds
Perf
volas
8.44 µs
7.00 µs
118,511
9837
57.11×
talib
25.87 µs
19.42 µs
38,658
23881
20.59×
stock_pandas
87.53 µs
57.46 µs
11,425
3447
6.96×
polars
142.30 µs
104.04 µs
7,027
457
3.84×
pandas
170.53 µs
120.98 µs
5,864
1110
3.30×
pandas_ta
528.66 µs
399.75 µs
1,892
952
1.00×
macd.signal
Candidate
Mean
Median
OPS
rounds
Perf
volas
14.73 µs
11.88 µs
67,896
9539
30.40×
talib
28.69 µs
20.67 µs
34,859
13529
17.47×
stock_pandas
102.01 µs
77.79 µs
9,803
3427
4.64×
polars
472.77 µs
134.21 µs
2,115
2081
2.69×
pandas
166.36 µs
147.25 µs
6,011
749
2.45×
pandas_ta
435.96 µs
360.96 µs
2,294
382
1.00×
rsi:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
13.20 µs
12.08 µs
75,736
23392
40.52×
talib
14.50 µs
14.00 µs
68,977
37038
34.97×
stock_pandas
69.62 µs
59.79 µs
14,363
3719
8.19×
pandas_ta
79.75 µs
66.60 µs
12,539
2974
7.35×
polars
229.67 µs
187.33 µs
4,354
561
2.61×
pandas
535.44 µs
489.58 µs
1,868
571
1.00×
willr:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
11.34 µs
10.00 µs
88,196
18032
26.58×
talib
14.55 µs
12.04 µs
68,707
26403
22.08×
pandas_ta
113.75 µs
101.58 µs
8,791
3128
2.62×
polars
3.78 ms
122.42 µs
265
49
2.17×
pandas
293.97 µs
265.83 µs
3,402
1226
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 151 / 158 covered indicators by the default ratio (0 exactly even, 7 slower).