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-07-29T09:31:35.619804+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
586.3 ns
586.8 ns
1,705,559
3
61.39×
talib
5.72 µs
5.72 µs
174,747
3
6.29×
polars
30.43 µs
30.49 µs
32,867
3
1.18×
pandas
36.43 µs
36.02 µs
27,450
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.34 µs
4.21 µs
230,504
39216
10.41×
polars
22.83 µs
22.33 µs
43,810
1585
1.96×
pandas
46.50 µs
43.79 µs
21,506
883
1.00×
copy
Candidate
Mean
Median
OPS
rounds
Perf
volas
315.3 ns
292.0 ns
3,171,539
115381
103.17×
polars
459.2 ns
417.0 ns
2,177,627
1842
72.24×
pandas
31.43 µs
30.12 µs
31,813
3572
1.00×
getcol
Candidate
Mean
Median
OPS
rounds
Perf
volas
344.4 ns
333.0 ns
2,903,517
114286
20.77×
polars
546.0 ns
541.0 ns
1,831,601
909
12.79×
pandas
7.05 µs
6.92 µs
141,894
1427
1.00×
mask
Candidate
Mean
Median
OPS
rounds
Perf
volas
11.30 µs
10.37 µs
88,465
16360
6.68×
polars
53.66 µs
47.67 µs
18,637
134
1.45×
pandas
72.17 µs
69.29 µs
13,855
1483
1.00×
setitem
Candidate
Mean
Median
OPS
rounds
Perf
volas
1.25 µs
1.21 µs
802,105
2184
12.14×
pandas
8.36 µs
7.92 µs
119,622
1834
1.85×
polars
15.38 µs
14.67 µs
65,019
536
1.00×
slice
Candidate
Mean
Median
OPS
rounds
Perf
polars
1.72 µs
1.71 µs
581,130
827
2.95×
volas
2.18 µs
2.13 µs
457,830
2397
2.37×
pandas
5.67 µs
5.04 µs
176,275
2020
1.00×
Batch indicator computation
Compute the indicator over the whole series, across every library.
atr:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
4.22 µs
4.21 µs
237,210
50211
110.12×
talib
14.07 µs
13.96 µs
71,092
29484
33.20×
stock_pandas
93.55 µs
92.71 µs
10,689
5385
5.00×
pandas_ta
109.23 µs
107.04 µs
9,155
3235
4.33×
polars
115.59 µs
111.79 µs
8,651
2562
4.14×
pandas
471.73 µs
463.37 µs
2,120
902
1.00×
boll.upper
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.91 µs
5.75 µs
169,164
49896
68.32×
talib
11.73 µs
11.46 µs
85,255
34238
34.28×
polars
84.40 µs
75.83 µs
11,849
2782
5.18×
pandas
145.66 µs
144.17 µs
6,865
2391
2.73×
stock_pandas
154.67 µs
151.21 µs
6,465
4619
2.60×
pandas_ta
397.35 µs
392.85 µs
2,517
1332
1.00×
ema:12
Candidate
Mean
Median
OPS
rounds
Perf
volas
5.14 µs
5.04 µs
194,420
59260
9.80×
talib
6.69 µs
6.63 µs
149,414
50103
7.46×
stock_pandas
36.16 µs
35.38 µs
27,653
7788
1.40×
polars
36.97 µs
36.71 µs
27,049
6848
1.35×
pandas
39.49 µs
38.33 µs
25,323
3605
1.29×
pandas_ta
51.13 µs
49.42 µs
19,559
4276
1.00×
hhv:10
Candidate
Mean
Median
OPS
rounds
Perf
volas
3.07 µs
3.04 µs
325,738
40610
18.08×
talib
5.63 µs
5.42 µs
177,590
39737
10.15×
polars
30.40 µs
32.42 µs
32,897
6055
1.70×
stock_pandas
47.17 µs
46.71 µs
21,198
6619
1.18×
pandas
56.37 µs
55.00 µs
17,741
3404
1.00×
llv:10
Candidate
Mean
Median
OPS
rounds
Perf
volas
3.90 µs
3.75 µs
256,274
54921
15.13×
talib
6.34 µs
5.83 µs
157,740
22967
9.73×
polars
33.60 µs
30.83 µs
29,759
4882
1.84×
stock_pandas
55.65 µs
51.42 µs
17,969
7016
1.10×
pandas
57.58 µs
56.75 µs
17,368
3837
1.00×
ma:20
Candidate
Mean
Median
OPS
rounds
Perf
volas
4.34 µs
4.25 µs
230,229
37559
15.15×
talib
6.06 µs
5.96 µs
165,025
48193
10.80×
polars
35.04 µs
34.50 µs
28,540
6282
1.87×
pandas
47.47 µs
46.83 µs
21,065
2872
1.37×
pandas_ta
49.32 µs
48.54 µs
20,275
5016
1.33×
stock_pandas
65.95 µs
64.38 µs
15,163
7466
1.00×
macd
Candidate
Mean
Median
OPS
rounds
Perf
volas
6.91 µs
6.71 µs
144,642
43165
38.47×
talib
17.46 µs
17.12 µs
57,289
26144
15.07×
stock_pandas
48.40 µs
47.21 µs
20,659
6945
5.47×
pandas
90.10 µs
87.75 µs
11,099
2463
2.94×
polars
88.35 µs
89.98 µs
11,318
3708
2.87×
pandas_ta
269.68 µs
258.13 µs
3,708
1379
1.00×
macd.signal
Candidate
Mean
Median
OPS
rounds
Perf
volas
11.45 µs
11.29 µs
87,322
40269
23.12×
talib
17.37 µs
17.17 µs
57,583
29889
15.21×
stock_pandas
59.38 µs
58.38 µs
16,840
8014
4.47×
pandas
125.19 µs
123.29 µs
7,988
2907
2.12×
polars
118.43 µs
123.50 µs
8,444
3266
2.11×
pandas_ta
265.10 µs
261.04 µs
3,772
1617
1.00×
rsi:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
11.89 µs
11.54 µs
84,118
35715
35.72×
talib
14.67 µs
14.00 µs
68,188
34935
29.45×
stock_pandas
53.80 µs
53.33 µs
18,586
8194
7.73×
pandas_ta
57.90 µs
56.54 µs
17,270
4611
7.29×
polars
183.42 µs
181.75 µs
5,452
2053
2.27×
pandas
415.05 µs
412.25 µs
2,409
969
1.00×
willr:14
Candidate
Mean
Median
OPS
rounds
Perf
volas
10.80 µs
10.46 µs
92,608
34433
20.62×
talib
11.56 µs
11.33 µs
86,507
27492
19.03×
polars
82.55 µs
71.92 µs
12,114
3344
3.00×
pandas_ta
92.60 µs
87.17 µs
10,799
3231
2.47×
pandas
221.87 µs
215.63 µs
4,507
2123
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).