Thread Leerzeichen-Regex lässt StackExchange ausfallen? (27 answers)
Opened by GwenDragon at 2016-07-21 13:24

clms
 2016-07-25 23:23
#185137 #185137
User since
2010-08-29
373 Artikel
BenutzerIn
[default_avatar]
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.

View full thread Leerzeichen-Regex lässt StackExchange ausfallen?