Обсуждая относительные преимущества использования index()
в Perl для поиска подстрок, я решил написать микро-тест, чтобы доказать, что я видел раньше, чем индекс быстрее, чем регулярные выражения при поиске подстроки.Вот код тестирования:
use strict;
use warnings;
use Benchmark qw(:all);
my @random_data;
for (1..100000) {
push(@random_data, int(rand(1000)));
}
my $warn_about_counts = 0;
my $count = 100;
my $search = '99';
cmpthese($count, {
'Using regex' => sub {
my $instances = 0;
my $regex = qr/$search/;
foreach my $i (@random_data) {
$instances++ if $i =~ $regex;
}
warn $instances if $warn_about_counts;
return;
},
'Uncompiled regex with scalar' => sub {
my $instances = 0;
foreach my $i (@random_data) {
$instances++ if $i =~ /$search/;
}
warn $instances if $warn_about_counts;
return;
},
'Uncompiled regex with literal' => sub {
my $instances = 0;
foreach my $i (@random_data) {
$instances++ if $i =~ /99/;
}
warn $instances if $warn_about_counts;
return;
},
'Using index' => sub {
my $instances = 0;
foreach my $i (@random_data) {
$instances++ if index($i, $search) > -1;
}
warn $instances if $warn_about_counts;
return;
},
});
Что меня удивило, так это то, как они работали (используя Perl 5.10.0 на последнем MacBook Pro).В порядке убывания скорости:
- Некомпилированное регулярное выражение с литералом (69,0 операций / сек)
- Использование индекса (61,0 операций / сек)
- Некомпилированное регулярное выражение со скаляром (56,8 операций в секунду)
- Использование регулярных выражений (17,0 операций в секунду)
Может ли кто-нибудь объяснить, что использует Perl voodoo для получения скорости двух несобственных регулярных выраженийвыполнить так же, как индексную операцию?Является ли это проблемой в данных, которые я использовал для генерации эталонного теста (в поисках вхождения 99 в 100 000 случайных целых чисел), или Perl способен выполнить оптимизацию во время выполнения?