Multi-threaded Rust from Python for Ventute AI Platform by Maxim KushnirMulti-threaded Rust from Python for Ventute AI Platform by Maxim Kushnir

Multi-threaded Rust from Python for Ventute AI Platform

Maxim Kushnir

Maxim Kushnir

PyO3 Rust py bridge

Call native, multi-threaded Rust from Python — and leave the GIL behind for CPU-bound work.

About this project. A standalone, generalized extraction of an architecture pattern from Ventute — a production AI-driven business-simulation platform — distilled into self-contained, runnable form. Published as a portfolio piece demonstrating high-performance Python/Rust interop and GIL-free parallel compute. Author: @m4xkushnir.

A minimal, domain-free showcase of the PyO3 + rayon pattern: a tight numeric loop written in Rust, exposed as an ordinary Python function, that releases Python's Global Interpreter Lock and fans the work across every core. The example task is a Monte-Carlo estimate of π — embarrassingly parallel, purely arithmetic, tiny data in and out.

Benchmark

Estimating π from 20,000,000 random samples, three ways, running the identical algorithm (same SplitMix64 PRNG, same draw order) so the comparison is like-for-like:
Implementation π estimate Throughput (M samples/s) Speedup Pure Python (1 thread) 3.14179 0.20 1.0× Rust PyO3 (1 thread) 3.14163 69.0 341× Rust PyO3 + rayon (8 threads) 3.14140 210.0 1039×
Measured on an 8-core machine, release build (opt-level=3, LTO). Your numbers will vary with CPU and core count — reproduce them with python python/benchmark.py. The two axes are independent: ~341× is the language/compilation win (native code vs the interpreter), and the further jump to ~1039× is the multi-core win the GIL denies to pure-Python threads.
Two honest caveats so the number means what it says:
The baseline is a naive pure-Python loop, not NumPy. That is the right comparison here because both sides run the same scalar algorithm — it isolates the cost of the interpreter itself. A vectorised NumPy baseline would be far faster (and a different lesson).
Most of the serial win is Python's per-operation interpreter overhead on a hot scalar loop; the parallel win on top is pure hardware the GIL otherwise leaves idle.

How it bypasses the GIL

Python's Global Interpreter Lock lets only one thread execute Python bytecode at a time. For I/O you can work around it; for CPU-bound work it is a hard ceiling — spawning four Python threads to crunch numbers gets you roughly one core's worth of throughput, because they take turns holding the lock.
Determinism is preserved: the work is split into a fixed number of chunks, each seeded independently, and the per-chunk hit counts are summed — so the estimate is identical for a given seed no matter how many threads rayon happens to use.
Like this project

Posted Jul 31, 2026

Showcased high-performance Python/Rust interop for AI platform Ventute.