Thread Leerzeichen-Regex lässt StackExchange ausfallen?
(27 answers)
Opened by GwenDragon at 2016-07-21 13:24
Ich habe es jetzt mit einem leicht modifizierten Beispiel ausprobiert.
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 use strict; use warnings; use 5.010; use Benchmark qw(:all :hireswallclock) ; my $inputA = "X".(" \t" x 200000)."A"; my $inputB = "X".(" \t" x 200000)."B"; my $c1A = <<'CODE'; my $s = $inputA; $s =~ s/[\s\u200c]+A/ A/; CODE my $c1B = <<'CODE'; my $s = $inputB; $s =~ s/[\s\u200c]+A/ A/; CODE my $c2A = <<'CODE'; my $s = $inputA; $s =~ s/(?<=\S)[\s\u200c]+A/ A/; CODE my $c2B = <<'CODE'; my $s = $inputB; $s =~ s/(?<=\S)[\s\u200c]+A/ A/; CODE timethis(50_000_000,$c1A); timethis(50_000_000,$c1B); timethis(50_000_000,$c2A); timethis(50_000_000,$c2B); Wenn gegen inputA gematched wird, ist die Regex ein Treffer, es findet also kein Backtracking statt, dafür muss der String verändert werden. Wenn gegen inputB gematched wird, ist die Regex kein Treffer, bei $c1B kann das Backtracking also stattfinden. Dann habe ich noch Muffis Vorschlag aufgegriffen. In den Fällen $c2A und $c2B wird das Backtracking durch die Look-Behind-Assertion als Anker vor dem \s+ verhindert. Ergebnis: Alle vier Varianten brauchen auf meiner Maschine mit Perl 5.20.2 ca. 4 Sekunden. Die Unterschiede liegen jeweils innerhalb der Schwankungsbreite zwischen zwei erneuten Durchläufen. Fazit: Die Regex-Engine scheint an dieser Stelle zu optimieren. Eine Verlangsammung durch Backtracking kann ich nicht feststellen. |