Skip to content

Improve large-string anchored full-match performance #1174

Description

@fglock

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions