在讨论在Perl中使用index()
搜索子字符串的相对优点时,我决定编写一个微基准来证明我之前看到的内容,而索引在查找子字符串时比正则表达式更快。以下是基准测试代码:
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;
},
});
我感到惊讶的是这些表现如何(在最近的MacBook Pro上使用Perl 5.10.0)。按速度降序排列:
任何人都能解释一下,为了获得两个未处理的正则表达式的执行速度以及索引操作,Perl正在使用什么voodoo?这是我用来生成基准测试的数据中的一个问题(寻找100,000个随机整数中出现的99个)还是Perl能够进行运行时优化?
答案 0 :(得分:2)
好吧,你的情况“使用正则表达式”是如此之慢,因为你每次都在编译它。尝试将其移出子程序。
答案 1 :(得分:2)
根据@ Ven'Tatsu的评论,我稍微改变了基准:
use strict; use warnings;
use Benchmark qw(cmpthese);
use Data::Random qw( rand_words );
use Data::Random::WordList;
my $wl = Data::Random::WordList->new;
my @data_1 = (rand_words( size => 10000 )) x 10;
my @data_2 = @data_1;
my $pat = 'a(?=b)';
my $re = qr/^$pat/;
cmpthese(1, {
'qr/$search/' => sub {
my $instances = grep /$re/, @data_1;
return;
},
'm/$search/' => sub {
my $search = 'a(?=b)';
my $instances = grep /^$search/, @data_2;
return;
},
});
在Windows XP上使用ActiveState perl
5.10.1:
Rate qr/$search/ m/$search/ qr/$search/ 5.40/s -- -73% m/$search/ 20.1/s 272% --
在带有草莓的perl
5.12.1:
Rate qr/$search/ m/$search/ qr/$search/ 6.42/s -- -66% m/$search/ 18.6/s 190% --
在ArchLinux上使用bleadperl
:
Rate qr/$search/ m/$search/ qr/$search/ 9.25/s -- -38% m/$search/ 14.8/s 60% --
答案 2 :(得分:1)
Perl优化了很多东西。没有特殊正则表达式特征和文字字符的模式允许perl的正则表达式引擎简化许多事情。使用use re 'debug'
可以向您显示幕后实际发生的情况。