Pyvorin vs Numba
Both tools turn Python into machine code through LLVM. The deciding factor is what your slow code looks like — and this page shows how to find out.
Published Feb 20, 2026
Numba and Pyvorin both use LLVM to turn Python into machine code, and that is almost where the similarity ends. Pyvorin Native 1.0.9 compiles plain Python scripts ahead of time, locally, without source changes. Numba compiles decorated numerical functions at call time, with deep NumPy integration and NVIDIA GPU support. If your slow code is array-oriented numerics, Numba was built for exactly that shape. If it is unmodified pure-Python application code, that is the ground Pyvorin was built to take. The rest of this page is about telling the two apart before you commit engineering time to either.
One honest disclosure up front: Pyvorin's published benchmark suite measures Pyvorin against CPython, not against Numba. We will not invent head-to-head figures. What we can do is compare the two tools on goals, constraints and workload fit, and show you how to measure your own code against both in an afternoon.
What Numba is optimising for
Numba is an open source, NumPy-aware optimising compiler sponsored by Anaconda and released under a BSD 2-clause licence. Its own project description states the scope plainly: a JIT compiler for numerical functions in Python. You decorate a function, and on first call Numba types the arguments, lowers the function through LLVM, and executes native code instead of bytecodes.
That scope statement matters more than any feature list. Numba's type system starts from NumPy arrays as typed memory regions. Code written against that model — vectorisable loops over contiguous arrays — compiles into tight machine code. Numba also generates ufuncs, C callbacks and automatically parallelised loops, and it can target NVIDIA GPUs through Numba CUDA, which lets you write GPU kernels in Python. Its homepage lists support for Intel and AMD x86, POWER8/9 and ARM CPUs including Apple silicon, NVIDIA GPUs, Python 3.9 through 3.12, and Windows, macOS and Linux, with prebuilt binaries distributed as conda packages and pip wheels.
The trade is well documented and worth repeating: Numba's fast path — nopython mode — supports a subset of Python. Functions that use unsupported language features fall back to object mode or raise. You write your code to fit the compiler, or you accept falling back to interpreted speed.
What Pyvorin is optimising for
Pyvorin targets a different problem: CPU-bound pure-Python code in ordinary scripts, compiled ahead of time without modification. The benchmark workloads Pyvorin publishes are unmodified Python programs — no decorators, no type annotations, no restructuring into an array style. Compilation happens locally and in-process through LLVM (via llvmlite), linked against a local runtime; the compile path contains no network code, so no source leaves the machine.
Where Pyvorin cannot take a function through the compiler, the behaviour is an honest fallback: the router runs the original code under ordinary CPython semantics and records that it did so. A function that fails to compile never crashes the program; it just does not get faster. The full mechanism is documented on the unsupported code and fallback page.
The support matrix is narrower than Numba's and should be stated plainly: Pyvorin requires CPython 3.11 or later, and the current shipped wheel is built for CPython 3.12 on 64-bit Linux. Numba's platform breadth — macOS, Windows, POWER, more Python versions — is a genuine advantage we will return to below.
Where Numba is the better choice
Your code is already NumPy-shaped. Most scientific Python spends its time in array operations, and Numba is engineered precisely around that data model. If your hot functions take arrays, do arithmetic over them and return arrays, Numba's @jit is close to free speed.
You need GPUs. Numba CUDA is the established way to write NVIDIA GPU kernels from Python. Pyvorin compiles for CPUs only; we are not going to pretend otherwise.
You need broad platform coverage. Numba runs on Windows and macOS, on x86 and ARM, and supports Python 3.9–3.12. If your fleet is heterogeneous, or pinned to Python 3.10 or earlier, Numba fits and Pyvorin does not.
Licence cost is a hard constraint. Numba is free, open source and permissively licensed, with a large community and years of production history behind it. Pyvorin is a commercial product: the package metadata carries an MIT licence, but using it beyond the trial requires an activated licence with tiered plans (Free, Starter at £49 per month, Team at £129, Business at £399, Enterprise custom), device-bound activation and 1%-sampled usage telemetry. For hobby work or budget-constrained teams, Numba wins that column outright.
You want decorator-level control. Choosing exactly which functions compile — and with which signatures — is a feature when you are tuning a known numerical kernel.
Where Pyvorin fits better
Your slow code is not array-shaped. Pyvorin's strongest published categories are object and OO manipulation (geomean 42.6x across the suite's two workloads), core integer and loop kernels (16.2x), image processing (14.1x), financial calculations (13.5x), simulation (11.8x) and numerical computing (11.4x). These are pure-Python loops and object graphs — the code Numba's nopython mode would reject, and the code a decorator-driven array rewrite would force you to redesign.
You cannot touch the source. Vendor scripts, regulated code, shared modules owned by another team: if editing is off the table, "add a decorator" is not an option. Pyvorin's measured workflow compiles the file as written.
You want compilation without a runtime JIT. Pyvorin compiles ahead of time and caches the result on disk (an LRU cache of 500 entries, keyed by source and compiler state). Batch jobs and CI pipelines get native speed from the first call in every process, with no warm-up window and no JIT working set to reason about.
Semantics matter more than speed. The router never changes program semantics to chase a number; where it cannot produce a correct, faster path, it declines and keeps CPython behaviour. There is no object-mode grey area — either the function ran natively or it ran as the original Python, and the fallback logger records which.
You are behind an air gap or a strict egress policy. Compilation is local and the licence gate supports offline grace periods (24 hours on trial tiers, 72 hours on Basic and Professional, 90 days on Enterprise), so a disconnected machine keeps working. The telemetry that does exist sends event metadata, never source code, and the compile path sends nothing at all.
The compilation model in practice
Numba's JIT runs at call time: the first call with a new argument signature triggers typing, lowering and compilation, and each distinct signature pays that cost again. Long-running numerical services amortise it easily; short processes and interactive work feel it on every start. Because compilation is embedded in the interpreter's execution, there is also a working set of compiled code to reason about when you profile.
Pyvorin's compilation runs before execution, and the result is cached on disk — an LRU cache of 500 entries keyed by a hash of the source, the function, the compilation options and the runtime and compiler state, with per-entry checksum validation. A warmed cache makes the second and subsequent processes as fast as the first, and python -m pyvorin bench reports compilation time separately from execution time so you can judge amortisation on your own schedule. Neither model is universally better; they differ in when you pay and who notices.
The asymmetric comparison, stated fairly
Numba asks you to change your code to fit its compiler and rewards you with excellent numerical and GPU performance on broad platforms, for free. Pyvorin asks you to change nothing and rewards you with ahead-of-time native code for CPU-bound pure-Python workloads, on CPython 3.11+ on Linux, for a licence fee. These are different products answering different questions, and the marketing habit of comparing their speedups directly is mostly noise. Speedup figures only mean something against the same workload, measured the same way.
A realistic engineering judgement looks like this. A quant team whose pricing engine is already vectorised NumPy and who want CUDA kernels stays with Numba — correctly. A data-operations team whose ETL bottlenecks are pure-Python transformation loops inside a larger CPython application, where rewriting into NumPy style is a month of risk for unknown gain, is the team Pyvorin exists for. Profile first. The profiler output, not this page, should make the decision.
Workload-fit matrix
| Your situation | Numba | Pyvorin |
|---|---|---|
| NumPy array kernels, vectorisable loops | Excellent fit; core design target | Compiles, but arrays are not its focus |
| NVIDIA GPU kernels from Python | Yes — Numba CUDA | CPU only |
| Pure-Python loops, objects, non-array code | Needs nopython-compatible rewrite | Primary design target |
| Code you cannot modify | Not applicable — decorators required | Compiles the file as written |
| Python 3.9 or 3.10, Windows or macOS | Supported | Not supported (CPython ≥3.11, Linux x86_64 wheel) |
| Budget is zero | Free, BSD-licensed | Commercial licence required beyond trial |
| Short-lived batch jobs, no JIT warm-up wanted | Pays JIT cost per process | AOT, disk-cached, warm from the first call |
| Commercial support and offline licence grace | Community support | Tiered plans with offline grace (24 h–90 days) |
What neither tool will fix
Both tools attack interpreted bytecode execution, so both leave the same class of problem untouched. In Pyvorin's own suite, the slower workloads are string manipulation (geomean 0.8x), parsing (0.9x), web request handling (0.9x) and compression (0.2x) — code that lives inside C library routines or churns small Python objects, where interpretation was never the bottleneck. Numba's nopython subset excludes most of that code before the question arises. If your profiler shows time in I/O, regular engines or library calls, expect neither tool to help and budget your evaluation accordingly. Profile first.
Measure your own workload
Both tools are quick to evaluate on your real code. For Pyvorin, the standard commands are:
# See which functions Pyvorin can take natively
python -m pyvorin support your_script.py
# Benchmark an entrypoint function
python -m pyvorin bench your_script.py --function your_entrypoint --runs 5
# Machine-readable output for CI
python -m pyvorin bench your_script.py --json
For Numba, the equivalent experiment is a small branch: add @jit(nopython=True) to your hot functions and see how many compile in nopython mode versus falling back. That fallback count is itself the most informative datum in this comparison — it tells you whether your codebase is Numba-shaped at all. Pyvorin's own numbers, reported in full — 71 workloads, 48 faster and 22 slower than CPython, geomean 3.09x, worst case 0.05x — live on the benchmarks page, with the methodology on benchmark methodology. Whatever you measure, measure it the way benchmarking correctly describes: same host, warm-up included, correctness checked on every run.
Where to go next
- Benchmarks — every measured CPython vs Pyvorin result, wins and losses included.
- Quick start — install Pyvorin and benchmark your first function in minutes.
- Unsupported code and the fallback path — what happens when Pyvorin declines to compile, in detail.
- Pyvorin vs Cython and Pyvorin vs PyPy — the neighbouring comparisons in this series.
Last reviewed 18 February 2026 against Pyvorin Native 1.0.9 (verified build of 12 September 2026) and Numba's published project documentation at numba.pydata.org and github.com/numba/numba: open source under BSD 2-clause, LLVM-based JIT for numerical Python, CUDA GPU support, Python 3.9–3.12, x86/POWER/ARM CPUs, Windows/macOS/Linux. No head-to-head Pyvorin–Numba benchmark exists; none is claimed on this page.