{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreifqvpf6oxjxifczfagdn4osxffbir7qjpc7tdxlyvgybp3vcnh34e",
"uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mplhoawoxs62"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreigzf2bhnt6wkrdn2ze2a3sliwzshtkitkf4wnmap2s4lfkgqtsrsi"
},
"mimeType": "image/webp",
"size": 81094
},
"path": "/ab_as_62eafcb6a433008952b/from-pythonpandas-to-rustc-taking-our-tick-simulation-from-140ms-to-microseconds-per-window-4e8f",
"publishedAt": "2026-07-01T11:51:26.000Z",
"site": "https://dev.to",
"tags": [
"rust",
"performance",
"showdev",
"python",
"https://livefinai.synlabs.pro/"
],
"textContent": "## TL;DR\n\nWe're a small ML lab building alpha models for a handful of partners. Our market **simulation** loop — the part that keeps you honest about look-ahead bias — was 900–1300 ms per window in Python/Pandas, which made every experiment a 6–20 hour run. We went **pandas → numpy → hand-written Rust + C++ models** and landed at 1–5 ms per window on a cheap cloud box (4–40 µs on a high-clock CPU). This is the honest engineering story, and an actual question at the end for anyone who does HFT/MM.\n\nNot a pitch — I'll explain why at the bottom.\n\n## The problem: simulation, not latency\n\nOur whole training stack is Python: feature engineering → targets → training → backtests → and the one that actually matters, **simulation** (strict, no look-ahead).\n\nSimulation is brutal on compute. On 1m/5m bars over years of history, a single run on a normal workstation took **6–20 hours**. For each window we compute several hundred features, then run inference. Data → features → inference of one window was **900–1300 ms**.\n\nWe never cared about that latency for trading. We cared because **every experiment took a day** , and I had a backlog of hypotheses to test.\n\n## Step 1: pandas → numpy\n\nBeing Python people, the first move was obvious: rip pandas out of the hot path and go numpy. Real win — **~140 ms/window**. We could finally evaluate models across more angles.\n\nBut rolling-window recomputation and allocation churn were still the ceiling, and 140 ms only let me run the basic experiments.\n\n## Step 2: accepting the language was the wall\n\nMy friend has written Rust for years and never shut up about it: _\"your Python is nonsense, rewrite it in Rust.\"_ We argued for years about whether Rust is always worth it.\n\nThis time I got it: no matter what CPU I throw at it, the GIL and Python's overhead cap me. There was no way up.\n\n## Step 3: Rust + C++\n\nNot fast, not easy — we rewrote **every feature in Rust** , with **O(1) incremental state per tick** instead of recomputing rolling windows. That single change killed both the allocation churn and the latency variance. Then we converted the **models to a C++ engine AOT-compiled for the target CPU** , called over FFI.\n\nResults, full cycle, one window:\n\nStage | Latency/window\n---|---\nPython / pandas | ~140 ms\nCheap cloud box (vCPU) | 1–5 ms\nHigh-clock AMD test rig | 4–40 µs\n\nSimulations that took hours now take minutes. The memory-leak whack-a-mole is gone.\n\n## The part I didn't expect\n\nThe interesting outcome wasn't prod speed — it's the experiments this **unlocked**. We can now run real **tick-level simulation** (not a backtest) to test ideas we simply couldn't touch before, including some inspired by Michael Levin's work (bioelectric / collective-behavior stuff that turns out useful well beyond biology). In Python that was infeasible; in Rust it's basically bounded only by infrastructure.\n\n## Verify it yourself (no cherry-picked CSVs)\n\nWe stream raw live signals to a public board. Every signal is written to public S3 at generation time, immutable, with a microsecond timestamp — so you can confirm there's **no look-ahead** : `signal_gen_time > bar_time`, for every single one. The demo box also reports its real inference latency (you'll see ms, not µs — cheap silicon, honest number).\n\n## Where we're NOT flexing\n\nWe have real data-feed latency and **zero colocation / kernel-bypass / exchange adjacency**. This is fast _compute_ , not a colocated HFT desk. Not pretending otherwise.\n\n## The honest question\n\nIf anyone here actually runs **HFT / market-making** in production: given fast compute but no colo (real feed latency), is any of this usable in prod? Our only idea so far is **adverse-selection defense for market-making** — skew/pull quotes ahead of a microstructure move. We might be completely wrong. I'd love a reality check from someone who's actually done it.\n\n## Why this isn't an ad\n\nWe don't sell to retail, and I doubt there are buyers for this among readers here. I'm writing it because this community appreciates a real Rust-rewrite story and will tear bad engineering apart — which is exactly what I want.\n\n## Rust is cool. That's the post.\n\n**Links**\n\n * Live board (raw signals + real inference latency): https://livefinai.synlabs.pro/\n\n",
"title": "From Python/Pandas to Rust/C++: taking our tick simulation from 140ms to microseconds per window"
}