# pperl 0.6.0 *2026-07-11 to 2026-07-15, 54 commits.* ## Language and runtime - **The interpreter is faster**: with the JIT off, pperl averages 108.6 on the perlbench suite, where perl5 scores 100, up from 85. Every benchmark of the suite scores at least 84, and the `while` loop and sub call benchmarks run faster than on perl5. ## JIT and parallelization - **The JIT compiler and auto-parallelization** work in pperl's default runtime; in 0.5.6 they worked only under `--pp`. Numeric `for`, `while` and `until` loops, nested loops and `if`/`else` in loop bodies compile to machine code, with integer arithmetic checked for overflow and floating-point expressions evaluated in perl's order, so results are those of the interpreter. A sum over 100 million integers takes 0.14 s against perl5's 2.76 s, and a 1000x1000 Mandelbrot render 214 ms against 12.5 s. - **Parallel loops**: a counting loop whose iterations only add to sums runs on several cores, with the result of a sequential run. A floating-point sum is split across cores only when every partial sum is exact; other floating-point sums run compiled on one core. Loops too short to pay for the threads stay sequential: 100,000 iterations for a flat loop, 512 for one with a nested loop. The 1000x1000 Mandelbrot render takes 51 ms in parallel. - **Strings in compiled loops**: concatenation and `.=`, `sprintf` with `%d` formats, `length`, `index` with a constant string, string comparisons, `uc`, `lc`, `ucfirst`, `lcfirst`, `chomp`, `reverse`, `x` and `substr` compile. A loop calling `index` with a constant string makes 253 million calls per second, perl5 26 million. - **Arrays and hashes in compiled loops**: array elements with constant or computed indexes, `push`, `pop`, list assignment, `$#a`, `foreach` over an array or over the default `$_`, `while (@a)` and hash elements compile, as do `defined`, `ref` and `++` or `--` used as a value. - **`map`, `grep`, `sort`, `join` and `split` in compiled loops**: `map` and `grep` blocks that compute a value, `sort { $a <=> $b }` and its descending form, `join` over an array and `split` on a literal pattern compile. `map` takes 0.13 and `grep` 0.17 of the time perl5 takes. - **Subroutine calls in compiled loops**: calls to named subs compile with the loop, including subs that take their arguments with `shift` or a signature, declare `my` variables, return early, or call themselves or each other recursively. A signature sub with optional parameters compiles once per argument count, and a branch that calls `die`, `warn`, `croak` or `confess` no longer keeps a sub from compiling. A recursive sub such as `fib` compiles on its own as well: `fib(30)` takes 17 ms instead of 538 ms, and the "Deep recursion" warning comes at the same depth as on perl5. - **Regular expressions in compiled loops**: matches, captures and substitutions with a constant replacement, `s/PAT/TEXT/` and `s/PAT/TEXT/g`, compile and run perl's regex engine, so `$&`, `$1` and `@-` are set as in the interpreter. Patterns with `(?{ })`, `m//g`, `s///e` and `s///r` stay interpreted. - **Scalar::Util and List::Util in compiled loops**: `blessed`, `reftype`, `refaddr`, `weaken`, `unweaken`, `isweak`, `looks_like_number` and `readonly` from Scalar::Util and `sum`, `sum0`, `product`, `min` and `max` from List::Util can be called in a compiled loop. ## Modules - **B::Deparse and B::Concise** work: the B module was revised against perl5's, so `B::Deparse` turns code references back into source and `B::Concise` prints op trees. Deparsing interpolated strings and chained element access such as `$h->{a}{b}` works, where it died. `B::CV::XSUB` and `B::CV::XSUBANY` exist, and loading B no longer warns about a missing `B::OBJECT` package. - **Data::Dumper** supports `Freezer` and `Toaster`, `Deparse`, `Sortkeys` with a code reference, `Purity` and `Deepcopy`, a `Seen` hash given by the caller, globs and regexps, with perl5's rules for quoting numbers. With `Sortkeys` under `use locale`, keys sort in the locale's collation order. It runs at about perl5's speed. - **XSLoader**: `XSLoader::load` succeeds for every module built into pperl, as for a statically linked module on perl5. A module that loads its compiled part in an `eval` and falls back to pure Perl on failure no longer takes the slower fallback: Data::Dumper did, and ran 2 to 5 times slower. - **List::Util**: `first`, `any` and the other functions that take a block call it as perl5 does, without a full sub call per element; `first` and `any` took 6 to 7 times perl5's time and take 1.2 times. `uniq` keeps `undef` as `undef`, `uniqint` returns integers and honours an overloaded `int`, and `uniqnum` keeps integers above 2**53 apart. - **Sub::Util**: calling `set_subname` again and again on the same sub no longer gets slower with every call or leaks memory. - **Scalar::Util**: `blessed`, `refaddr`, `reftype`, `weaken`, `unweaken` and `isweak` are the `builtin::` functions, as in Scalar::Util on perl5. - **Function prototypes**: the functions of Time::HiRes, Scalar::Util, MIME::Base64 and MIME::QuotedPrint carry the prototypes perl5 gives them. With Time::HiRes's `time` imported, `time - $t0` subtracts instead of calling `time(-$t0)`. - **File::Spec**: the Unix functions that are XS on perl5 are native in pperl; `canonpath` runs at perl5's speed, where it took 12.8 times as long. ## Command line - **The `--pp` runtime is removed.** pperl has one runtime; `--pp` and the options only it supported, `--cache`, `--flush`, `--daemon`, `--client`, `--stop`, `--optree`, `--from-json`, `--trace`, `--timeout`, `--dump-optree` and `--compare-bytecode`, are gone. `-c` checks syntax with the parser that runs the program, so its messages and exit codes are perl5's; it used the other runtime's parser before. ## Distribution - **Static and cross-architecture builds**: pperl builds as a static x86-64 binary against musl, and as static AArch64 and RISC-V binaries with the JIT and auto-parallelization. Release binaries come with SHA-256 sums, and each must pass a smoke test, run under emulation for AArch64 and RISC-V. ## Documentation - **One runtime in the documentation**: the "Runtimes" page, the reference pages of the `--pp` runtime's modules in every language and every mention of `--pp` are removed, and the reference section is titled "Reference". - **JIT guide**: the architecture guide's JIT chapter is rewritten for the compiler of this release, covering what it compiles, how it keeps results exact and how to watch it work. The pages on writing fast pperl code, on measuring and on concurrent execution are brought in line with it. - **Module reference**: the pages of Devel::Peek, Hash::Util, List::Util, Math::GMP, the PDL modules, Peta::FFI, SDBM_File and mro are expanded and corrected, and their code examples are highlighted as Perl. - **Serbian translation**: links in ten perlfunc pages showed control characters instead of their labels; they are repaired, and the Serbian PDF builds.