Parallel word count (Monte Cristo)
Parallel word-frequency count over ~2.7 MB of Project Gutenberg text. Each runner uses its idiomatic CPU-parallel primitive.
Compile time · median (cold)
Full statistics
| Runner | N | Compile | Runtime | P95 | Stddev | RSS | vs pipit | Status |
|---|---|---|---|---|---|---|---|---|
| Native Gocompiled | 7 | 113 ms | 22.9 ms | 24.2 ms | 800 µs | 1.62 GiB | 34.3× | OK |
| Pipitbytecode VM | 7 | 3.29 ms | 90.4 ms | 93.7 ms | 1.50 ms | 592 MiB | 1.00× | OK |
| CPython 3.14bytecode VM | 7 | 843 µs | 190 ms | 193 ms | 1.45 ms | n/a | 0.26× | OK |
| PyPy 7.3tracing JIT | 7 | 602 µs | 298 ms | 299 ms | 1.78 ms | n/a | 0.18× | OK |
| tengobytecode VM | 0 | n/a | n/a | n/a | n/a | n/a | n/a | no data |
| scriggobytecode VM | 0 | n/a | n/a | n/a | n/a | n/a | n/a | unsupported |
| mvmbytecode VM | 7 | 800 µs | 256 ms | 266 ms | 9.14 ms | 1.69 GiB | 0.24× | OK |
| yaegiAST walker | 0 | n/a | n/a | n/a | n/a | n/a | n/a | no data |
Workload & symmetry rules
Workload
- Load The Count of Monte Cristo (Project Gutenberg #1184) corpus from disk.
- Split into 16 word-aligned chunks.
- Spawn 16 workers (
goroutine+WaitGroupon Go/pipit;multiprocessing.Poolon Python). - Each worker tokenises via byte-walk and builds a local
word → countmap. - Merge maps, compute top-50 by
(count desc, word asc)via hand-rolled insertion-sort.
Symmetry rules
- Each runner uses its idiomatic CPU-parallel primitive. Python's
multiprocessing.Pool(notthreading, because of the GIL). - No
str.split, noregexp, nosort.*/sorted(key=...): tokenisation and ranking are hand-rolled.
Why this benchmark exists
Directly measures the GIL-free advantage. Pipit inherits Go's goroutine scheduler; CPython has to fork.
Source code
pipit / Go
pipit_source.gonative Go
native_main.goCPython / PyPy
cpython.py