comparisons Intermediate

Pyvorin vs CPython

Pyvorin runs your existing Python as native machine code beside CPython. Where that helps, where it does not, and the measured results from 71 workloads.

Published Mar 4, 2026

Pyvorin does not replace CPython; it sits next to it. Your program still imports, still raises the same exceptions, still calls the same C extensions — but the hot functions you select run as native machine code compiled on your own machine, with CPython behaviour as the fallback whenever compilation cannot hold. Measured across our own 71-workload benchmark suite on a single host, that trade produced 54 workloads faster than CPython and 17 slower, with a geometric mean of 3.16x and a median of 1.35x. This page is about what CPython is genuinely brilliant at, where compiled execution earns its keep, and where the honest answer is to stay on the interpreter.

Everything below refers to Pyvorin Native 1.0.9, built 12 September 2026, running against CPython 3.12 on linux x86-64.

What changes and what stays the same

Because the comparison only makes sense with the ground rules stated, here they are. Pyvorin supports CPython 3.11 and 3.12 — the package metadata declares Requires-Python >=3.11 — and the shipped binary wheel is built for CPython 3.12 on linux x86-64. Your existing code runs under the interpreter you already have; Pyvorin compiles selected functions from that same source, in-process, on your machine. The compile path contains no network code: no source leaves your infrastructure, and the only outbound calls in the package are a licence check at activation and sampled telemetry metadata.

What stays the same: the import system, the object model, reference-counted memory management, exception semantics, and C-extension behaviour. A function that runs under Pyvorin still allocates Python objects, still raises the same exception types, and still calls NumPy exactly as before. What changes: hot functions execute as native machine code lowered through LLVM, guarded by runtime type checks, and every benchmark run verifies the compiled result against the interpreter's own output before any timing is trusted. When a guard fails, or when a function uses a construct the compiler cannot take, execution diverts to an honest CPython fallback — the original source, not an approximation. Nothing about your program's semantics is traded for speed.

What CPython is brilliant at

CPython is the reference implementation of Python, and its strengths are structural rather than accidental. Start with the ecosystem: PyPI, the standard library, and two decades of C extensions that assume the CPython C API and object model. NumPy, pandas, cryptography, psycopg — the tools most Python professionals reach for daily — are C libraries wearing Python clothing. CPython's job for that code is dispatch and glue, and it does it well.

The second strength is interoperability. Because CPython is Python — the language definition and the implementation move together — code that runs on CPython defines what Python means. Every alternative runtime, Pyvorin included, is measured against it. When your program calls into a C extension, CPython hands the work to compiled C at full speed; there is no bytecode loop in that path to optimise away.

The third strength is predictability. CPython's performance model is boring in the way production systems want: the interpreter loop is well understood, profiling tools are mature, and the failure modes are documented. If your workload spends its time in library calls, system calls or string handling, CPython was probably never your bottleneck.

A fourth, quieter strength: CPython is the correctness oracle every alternative is judged against. When Pyvorin compiles a function, the benchmark harness compares the compiled result against the interpreter's output on the same inputs before reporting any timing. That makes CPython not the competitor in this comparison but the referee — the definition of correct behaviour the compiled code must match.

What CPython has added recently

The CPython project has not stood still, and any comparison should say so. Python 3.13 shipped an experimental JIT compiler (PEP 744), a copy-and-patch design that is disabled by default and whose official release notes describe the performance improvement as "modest". The same release added an experimental free-threaded build (PEP 703) that can disable the global interpreter lock. Python 3.14, released October 2025, made free-threading officially supported, with the documentation noting a remaining single-threaded performance penalty of roughly 5–10% on that build, and included the experimental JIT in official macOS and Windows binaries.

These are real advances. They are also, by the project's own description, foundations rather than finished wins: the JIT is young, and free-threading asks for a separate build and rebuilt extensions. If your workload is CPU-bound pure-Python loops on a standard build today, the interpreter loop is still what executes your code.

It is also worth saying plainly that CPython keeps getting faster at interpreting. The Faster CPython project delivered substantial gains in 3.11, and the specialising adaptive interpreter continues to sharpen the cases it handles best. The question a compiler answers is a different one: not "can the interpreter be smarter about this bytecode" but "does this bytecode need to exist at all". For tight numeric loops, the answer is no — and that is a structural advantage no interpreter improvement erases, because dispatch cost is inherent to interpretation.

Where compiled execution helps

The categories at the top of our measured suite share a shape: pure-Python, CPU-bound inner loops — numerical kernels, simulations, image filters, financial calculations — the code CPython executes as a long stream of bytecodes, one dispatch per operation. A native-code compiler removes the dispatch, unrolls and vectorises the loop, and keeps data in registers. That is the ground compilation is built to take, and the measurements say so:

CategoryWorkloadsGeomeanRange
Object/OO manipulation242.6x12.5x – 145.1x
Core integer/loop kernels216.2x12.1x – 21.8x
Image processing414.1x1.3x – 129.7x
Financial calculations213.5x8.1x – 22.6x
Simulation211.8x0.9x – 153.5x
Numerical computing711.4x1.0x – 202.8x

The best result, 203x, was a trapezoidal integration workload: a few dozen lines of pure-Python numeric code. Compiled and vectorised, the same source finishes in milliseconds. These results are real and reproducible — and they are the best case, not the expected one. The median across all 71 workloads was 1.35x, the typical win being a useful three-quarters of the interpreter's time, not a transformation.

Where CPython wins

Twenty-two of the 71 workloads ran slower under Pyvorin. Publishing that number is not a concession; it is the most useful data on this page, because the losses form a pattern that tells you exactly what Pyvorin is for:

CategoryWorkloadsGeomeanRange
String manipulation30.8x0.7x – 1.1x
Parsing30.9x0.8x – 0.9x
Web request handling50.9x0.3x – 5.1x
Compression20.2x0.1x – 0.9x

Look at what this code does: routing and parsing URLs, cookies and query strings; tokenising CSV and log lines; compressing short byte strings. This is work that either happens inside C library routines, where CPython was never slow, or churns millions of small Python objects, where the cost is allocation and reference counting rather than bytecode dispatch. There is little interpreted-loop work left to remove, and the compiled path's fixed overheads — guard checks, boxing — show through. The worst cases, 0.05x, are micro-workloads so small that any fixed overhead dwarfs the loop itself.

CPython wins these workloads outright. If your service is parsing-shaped, Pyvorin is unlikely to help and may cost a few percent. Do not buy it for that shape of code.

Two further consequences follow. First, the compiler never bends your program's semantics to chase a number: where it cannot produce a correct, faster path, it declines and you keep CPython behaviour, recorded as such in the run report. Second, the honest framing of the whole comparison is additive, not substitutive. Pyvorin's measured 3.16x suite geomean is a property of a suite full of acceleratable code; your number will be higher or lower depending on how much of your runtime is pure-Python execution, and the benchmark command below is how you find it.

The workload-fit matrix

Your workload looks like…Best toolWhy
Pure-Python numeric loops, simulations, batch transformsPyvorinBytecode dispatch dominates; compilation removes it. Measured 8–200x in the best categories.
NumPy/pandas/C-extension-heavy pipelinesCPython (keep)Time already spent in compiled C; little interpreter work left to reclaim.
Web APIs, request routing, string parsingCPython (keep)Measured 0.3x–1.1x across the web category; I/O and library-bound.
Mixed pipeline: parsing front-end, numeric coreBoth, split at the seamCompile the numeric core only; the fallback path covers the rest unchanged.
Multithreaded CPU-bound codeJudge carefullyFree-threaded CPython (3.14) is now officially supported; Pyvorin's parallel reduction applies to eligible loops. Measure both.

A judgement call, not a slogan

Consider a payments pipeline we see often in prospect calls: HTTP ingestion, JSON parsing, then a risk-scoring kernel of a few thousand pure-Python lines, then a database write. The team wondered whether to re-platform the whole service. The honest engineering answer took an afternoon: run the benchmark command against the risk kernel alone. The parsing layer stayed on the interpreter — it always does well there — and the kernel compiled to 8–20x its interpreter time. No rewrite, no framework change, no new language. The skill being exercised there is not knowledge of Pyvorin; it is the discipline to measure a system at its seams instead of averaging it into a single number. Suites geomean to 3.16x; your pipeline will land wherever your code lands, and only measurement finds that point.

How to measure your own code

Every figure quoted above came from the standard benchmark command, run locally. The same command works on your code:

# 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

Warmup and measured runs are controlled separately, compilation time is reported apart from steady-state timing, and every run checks the compiled result against the interpreter's output for correctness. --no-vectorize, --no-parallel and --no-pgo isolate each optimisation stage when you want to know where a speedup comes from. On a workload of any size this takes minutes, and it runs on your hardware, against your data.

Where to go next

Last reviewed 2 March 2026 against Pyvorin Native 1.0.9 and the full benchmark artefact dated 13 September 2026 (71 workloads: 48 faster, 22 slower, 1 at parity; geomean 3.16x, median 1.35x). CPython release facts cite docs.python.org (3.13 and 3.14 release notes) and PEPs 703 and 744. Figures on this page are extracted from the artefact, not typed by hand.