Benchmarks
Looking for the indicator library's numbers?
This page is about Wickra Pico. Wickra's own indicator benchmarks — the comparison against TA-Lib, talipp, pandas-ta and the other Rust TA crates — live at wickra.org.
wickra-pico is a hardware showcase, not a library: it runs the no_std Wickra signal kernel (an EMA(9)/EMA(21) cross) bare-metal on a Raspberry Pi Pico. The numbers that matter here are the per-update cost of the signal kernel — on a host in nanoseconds, and on the target MCU in cycles — plus the proof that both paths produce a byte-identical result.
Methodology
- Host. A criterion bench in
crates/wickra-pico-signaltimes a singleupdatecall on the steady-state O(1) path (warmed past the EMA warmup), on x86-64. This is the same kernel code the firmware runs. - MCU. The RP2040 target is a Cortex-M0+ built for
thumbv6m-none-eabi. The firmware reads the SysTick counter around a fixed batch ofupdatecalls and reports mean cycles per update — the same code path as the host bench, on the chip it actually ships to. - Determinism.
wickra-pico-hostruns the identical tick feed through the kernel withstdand asserts the EMA(9)/EMA(21) cross decisions are byte-identical to the MCU run. Cross-target determinism is the property the showcase demonstrates; seedocs/DETERMINISM.md. - Allocation. Zero, by construction — the signal kernel is
#![no_std]with no allocator linked. There is nothing to measure; the absence is the point, and CI enforces it by building forthumbv6m-none-eabi.
Results
The host column is measured by cargo bench -p wickra-pico-signal (benches/signal.rs: on_tick on the steady-state path past the EMA warmup, criterion median on a Ryzen 9 9950X, Windows, Rust 1.92, rounded — indicative, not a CI-pinned regression gate; the nightly bench tracks drift and CodSpeed counts instructions on every pull request). The RP2040 column lands with the on-device SysTick measurement.
| Signal | Host (ns/update) | RP2040 Cortex-M0+ (cycles/update) | Allocations |
|---|---|---|---|
| EMA(9)/EMA(21) cross | ~6 | pending | 0 |
A full replay from reset over 4096 ticks (on_tick from reset over 4096 ticks) takes ~17 µs, i.e. ~4 ns per tick including the warmup.
Each EMA update is a single multiply-add on the running value, so the cost is flat regardless of the period; the cross is just the two updates plus a comparison. The Cortex-M0+ has no hardware divide and no FPU, so the on-device figure reflects the soft-float path the firmware links — which is exactly why the kernel is written to stay on integer/f32 operations with a bounded per-tick cost.
Reproducing
# Host, per-update criterion bench:
cargo bench -p wickra-pico-signal
# On-device cycle counts (requires the Pico toolchain + a board or QEMU):
cargo run -p wickra-pico-host --releaseAll figures are steady-state, post-warmup, single-update costs. Because every update is O(1) with no allocation, the worst-case per-update latency is bounded — the property that matters for bare-metal real-time firmware, more than the mean.
The numbers above are the ones in the repository's BENCHMARKS.md, measured with the commands it names.