It's just a simple regex benchmark for different programming languages.
"All benchmarks are wrong, but some are useful" ~ Szilard (cited from benchm-ml)
We hope this benchmark can be helpful. If you take this as a guidance on choosing a language: Remember your choice should not only be about performance, but each language also has its engine and offers different features (like UTF support, backreferences, capturing groups ...).
| Language | Total(ms) |
|---|---|
| 1. Rust | 15.53 |
| 2. C++ SRELL | 24.82 |
| 3. C# .Net | 57.69 |
| 4. Nim Regex | 59.50 |
| 5. PHP | 70.66 |
| 6. Nim | 70.84 |
| 7. Julia | 108.77 |
| 8. Crystal | 151.15 |
| 9. Javascript Node 26 | 158.21 |
Base image: ubuntu:24.04 (noble, amd64). Everything runs from a single Docker image whose entrypoint (benchmark/monolithic-from-sources/run-benchmarks.php, executed by PHP) builds and times each language.
- C: gcc 14.4.0 & PCRE2 10.47 (both built from source; C is compiled with gcc 14)
- Crystal: Crystal 1.21.0 (LLVM 22.1.0 bundled)
- C++: g++ 16.1.0 | Boost 1.91.0 (both built from source; C++ is compiled with g++ 16)
- C#: dotnet 10
- D: DMD 2.112.0 | LDC 1.42.0
- Dart: Dart 3.12.2
- Go: go 1.26.5
- Java: Eclipse Temurin OpenJDK 26.0.1+8
- Javascript: Node 24.18.0 (LTS) and Node 26.5.0 (Current) => two result rows
- Julia: Julia 1.12.6
- Kotlin: kotlinc-jvm 2.4.10
- Nim: Nim 2.2.10 + nim-regex 0.26.3
- Perl: perl 5.44.0 (built from source)
- PHP: PHP 8.5
- Python: Python 3.14 | PyPy 7.3.23 (PyPy2 & PyPy3)
- Ruby: ruby 4.0.6 (built from source)
- Rust: rustc 1.97.1 & regex 1.13.1
Note on exactness: Everything is pinned to an exact version except the three installed from apt feeds below, which are pinned to the minor version and track the latest patch (the feeds don't retain older patches, so an exact pin would break on rebuild):
- C# / .NET:
dotnet-sdk-10.0from the Microsoft prod feed → latest 10.0.x - PHP:
php8.5-clifromppa:ondrej/php→ latest 8.5.x - Python 3:
python3.14from the deadsnakes PPA → latest 3.14.x
PHP 8.5 is reused as the benchmark orchestrator runtime.
Check each results/ file for their specific methodology.
They might differ in the exact execution.
However, we try to keep them comparable.
The input text is a concatenation of Learn X in Y minutes repository.
Feel free to open an issue for more/other text inputs.
- Email:
[\w\.+-]+@[\w\.-]+\.[\w\.-]+ - URI:
[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)? - IPv4:
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])
The above regex patterns aren't the best nor the optimal. The focus is the benchmark, not the matching.
The patterns are applied to the whole file.
Measuring is done inside the programs to avoid including startup, reading and writing times on results.
Elapsed time includes pattern compilation, find and count occurrences.
Usually, an average out of 10 runs is measured.
We serve two ways of running the benchmark. One is a fully isolated docker container running all of them, being able to offer a fully equalised OS base. The other is hosting one container per language, reusing existing images for most of the languages (accompanied by some custom images), which is much faster but not as equalised on the OS-level, tho we try to keep it as similar as possible. They are independent and only hand-synced.
docker build -t regex-benchmark benchmark/monolithic-from-sources
docker run --rm -v $(pwd):/var/regex regex-benchmarkNote: the image builds GCC 14, GCC 16, PCRE2, Boost, Perl and Ruby from source, so the initial
docker buildcan take a long time (potentially over an hour on a typical machine) and needs several GB of disk. Subsequent builds reuse the Docker layer cache.
docker compose -f benchmark/from-images/docker-compose.yml up --buildSee its README for the per-language tags and the fairness caveats when comparing its table to the single-image one.
All contributions are welcome, from tiny optimizations to new implementations.
There are only a few requirements:
- Follow the style of the current implementations
- Use the default settings for the regex engine
- Update
Dockerfileif it's necessary
- mariomka and all contributors for their work on the benchmark
- Heng Li's for his work on Benchmark of Regex Libraries
- A "challenge" on Madrid Devs group, who inspired mariomka for the original benchmark
- Programming subreddit, helped mariomka to improve the original benchmark
MIT © Mario Juárez.