Summary
Large-string full matches are dramatically slower on both PerlOnJava backends
than on standard Perl. The cost is in regex matching, not in string append
buffer growth.
Reproducer
use strict;
use warnings;
use Time::HiRes qw(time);
my $bytes = 5 * 1024 * 1024;
my $iterations = 400;
my $s = 'x' x $bytes;
my $start = time;
for (1 .. $iterations) {
die "full match mismatch\n" unless $s =~ /^x+\z/;
}
printf "seconds=%.3f\n", time - $start;
Measurements
On the same machine:
| Runtime |
Time |
| Standard Perl |
0.104 s |
| PerlOnJava JVM backend |
57.120 s |
| PerlOnJava interpreter backend |
49.627 s |
That is roughly 475–550 times slower for repeated full matches of the same
5 MiB string.
Append is not the dominant cost
A companion benchmark grew a string from 2 MiB to 5.1 MiB with 400 appends of
8 KiB. Append-only completed in 1.428 s on the JVM backend and 1.680 s on the
interpreter backend, including JVM startup. Adding a full ^x+\z match each
iteration raised the times to 38.554 s and 45.045 s, respectively. Standard
Perl completed the combined benchmark in 0.202 s.
The user's original append-plus-regex workload is therefore accidentally
quadratic because it repeatedly scans a growing string, but PerlOnJava adds a
very large per-character matching overhead. A simple start-anchored probe
(^x) did not exhibit the same magnitude of slowdown.
Suggested investigation and acceptance coverage
- Profile the Joni/regex execution path for
^x+\z over multi-megabyte
strings, including allocations and matcher setup.
- Determine why the JVM and interpreter backends have similar overhead.
- Add a focused tracked performance regression benchmark with a conservative
threshold that catches multi-order-of-magnitude regressions without making
CI timing-sensitive.
- Verify the optimized path preserves captures, anchors, Unicode semantics,
and pathological-pattern safeguards.
Summary
Large-string full matches are dramatically slower on both PerlOnJava backends
than on standard Perl. The cost is in regex matching, not in string append
buffer growth.
Reproducer
Measurements
On the same machine:
That is roughly 475–550 times slower for repeated full matches of the same
5 MiB string.
Append is not the dominant cost
A companion benchmark grew a string from 2 MiB to 5.1 MiB with 400 appends of
8 KiB. Append-only completed in 1.428 s on the JVM backend and 1.680 s on the
interpreter backend, including JVM startup. Adding a full
^x+\zmatch eachiteration raised the times to 38.554 s and 45.045 s, respectively. Standard
Perl completed the combined benchmark in 0.202 s.
The user's original append-plus-regex workload is therefore accidentally
quadratic because it repeatedly scans a growing string, but PerlOnJava adds a
very large per-character matching overhead. A simple start-anchored probe
(
^x) did not exhibit the same magnitude of slowdown.Suggested investigation and acceptance coverage
^x+\zover multi-megabytestrings, including allocations and matcher setup.
threshold that catches multi-order-of-magnitude regressions without making
CI timing-sensitive.
and pathological-pattern safeguards.