# pperl 0.6.3 *2026-07-18 to 2026-07-23, 35 commits.* ## Language and runtime - **Start-up**: pperl starts no worker threads until a loop first runs in parallel, so a program that never does starts none; creating them took about 1 ms of every start. In the benchmark suite's start-up rows pperl went from 1.277 to 1.136 times perl5's start-up time (geometric mean). ## JIT and parallelization - **Subroutines called from compiled loops** compile together with the loop when their body contains loops of its own (`while`, C-style `for`, ranges, nested loops) or reads a lexical variable of the enclosing scope, a closure. - **Array references in compiled loops**: `for (@$A)`, `$A->[$i][$j]` and loop bounds such as `scalar(@$A)` compile, so matrix code written over arrays of arrays, such as a matrix difference or a matrix product's triple loop, compiles as one nest of loops. - **Hashes in compiled loops**: hash elements with computed keys, such as `$h{$i & 1023}`, can be read and written in a compiled loop, and `%h = (key => value, ...)` with constant keys and numeric values compiles too. - **Strings in compiled loops**: `substr`, `uc`, `lc`, `ucfirst`, `lcfirst` and `reverse` compile as parts of larger expressions, as in `length(substr($s, 0, $n))`, and so do string comparisons and concatenations of array elements. Loops whose condition is a pattern match without `/g` or a `length`, such as `while ($s =~ /x/)` or `while (length $s)`, compile. - **Nested loops**: C-style `for (;;)` loops nested in other loops compile. Whether a loop is worth compiling is judged by the work of its body, inner loops included, so `for (0..10) { for (0..9999) {...} }` compiles although its outer loop runs only 11 times. - **`do {...} while` and `do {...} until`** loops compile. - **`map` and `grep`** statements of the form `@dst = map {...} @src` compile on their own, outside any loop, when the source array is large enough to repay the compilation. - **More loops compile**: whether a loop compiled could depend on the code around it, for example on a preceding statement with a `?:` conditional; such loops now compile. So do loops that use the result of a comparison as a number, as in `$n += ($x > $y)` or `$a[$i == 0]`. - **Parallel reductions over arrays**: a loop that adds up values read from arrays it does not write, such as `$sum += $a[$i]`, runs in parallel on several cores. - **JIT compilation cost**: finding and compiling a program's loops takes less time. A program of 600 short loops ran in 0.371 s instead of 0.577 s, and the search for loops now grows with the size of the program rather than with its square. ## Modules - **MIME::Base64**: `encode_base64` encodes inputs of 1 MiB and more on several cores, with output identical to the serial encoder; on 32 MiB it is 2.85 times as fast as perl5's MIME::Base64. - **Digest::SHA**: methods that return their object, such as `add`, kept an extra reference to it, so a Digest::SHA object was never freed. - **POSIX**: `POSIX::read` accepts a reference to its buffer as well as the buffer itself, as on perl5, and the data it reads is tainted under `-T`. - **PDL**: `lu_backsub` given its right-hand side as a plain Perl value no longer reads freed memory. ## Command line - **Version reporting**: `pperl -v` and `pperl -V` name perl 5.44 as the version pperl is compatible with, and `$Config{version}` is 5.44.99, matching `$^V`; all three said 5.42.0. ## Documentation - **Translations**: the "Graphics with Perl" guide is translated into German, French, Italian, Czech, Greek, Danish, Hebrew, Ukrainian, Croatian and Spanish.