ab(?>.*?cd)
ab(?:(?!cd).)*+cd
ab(?:[^c]++|c(?!d))*+cd
В простом случае, как в предыдущем вопросе, с длинной тестовой строкой и следующим кодом на Perl 5.12, ответ таков: первое регулярное выражение намного превосходит остальные , второе самый медленный (как и предполагалось).
Это были результаты в итерациях в секунду (масштабированные до самого медленного):
- 23,49 x iter / sec
- 1,00 x iter / sec
- 3.35 x iter / sec
Используя код:
use v5.12;
use Benchmark qw(:hireswallclock :all);
my $str = '';
my $ab = 'ab' x 1024**2;
$str .= $ab . 'cd';
$str .= $ab . 'cde';
$str .= $ab . 'cdef';
$str .= $ab . 'cdefg';
$str .= $ab . 'cdefgh';
printf "Test string length: %.2f MiB\n", (length($str)/1024**2);
timethese(-10, {
'0:index' => sub { index($str, 'cdefgh') },
'1:match' => sub { $str =~ /ab(?>.*?cdefgh)/ },
'1:fail' => sub { $str =~ /ab(?>.*?cdefgg)/ },
'2:match' => sub { $str =~ /ab(?:(?!cdefgh).)*+cdefgh/ },
'2:fail' => sub { $str =~ /ab(?:(?!cdefgg).)*+cdefgg/ },
'3:match' => sub { $str =~ /ab(?:[^c]++|c(?!defgh))*+cdefgh/ },
'3:fail' => sub { $str =~ /ab(?:[^c]++|c(?!defgg))*+cdefgg/ },
});
Выход:
Test string length: 10.00 MiB
Benchmark: running 0:index, 1:fail, 1:match, 2:fail, 2:match, 3:fail, 3:match for at least 10 CPU seconds...
0:index: 11.0578 wallclock secs (10.00 usr + 0.00 sys = 10.00 CPU) @ 246.70/s (n=2467)
1:fail: 11.0379 wallclock secs (10.05 usr + 0.00 sys = 10.05 CPU) @ 245.05/s (n=2462)
1:match: 11.9981 wallclock secs (10.08 usr + 0.00 sys = 10.08 CPU) @ 63.80/s (n=643)
2:fail: 12.0531 wallclock secs (10.53 usr + 0.00 sys = 10.53 CPU) @ 255.25/s (n=2688)
2:match: 11.0573 wallclock secs (10.13 usr + 0.00 sys = 10.13 CPU) @ 2.67/s (n=27)
3:fail: 12.8325 wallclock secs (10.78 usr + 0.00 sys = 10.78 CPU) @ 266.58/s (n=2874)
3:match: 11.8457 wallclock secs (10.09 usr + 0.00 sys = 10.09 CPU) @ 9.31/s (n=94)
Ошибка в этих случаях быстрая. Похоже, это связано с тем, что Perl, вероятно, сначала сканирует все простые строки подсовпадений и завершается неудачей, если они не найдены (такая же скорость, как у index
).