在讨论在 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)。按速度降序排列:
- 未编译的带有文字的正则表达式(69.0 次操作/秒)
- 使用索引(61.0 次操作/秒)
- 未编译的标量正则表达式(56.8 次操作/秒)
- 使用正则表达式(17.0 次操作/秒)
谁能解释一下 voodoo Perl 使用什么来获得两个未编译的正则表达式以及索引操作的执行速度?这是我用来生成基准的数据中的问题(查找 100,000 个随机整数中 99 的出现次数)还是 Perl 能够进行运行时优化?
最佳答案
批发修订版
根据@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;
},
});
在带有 ActiveState perl
5.10.1 的 Windows XP 上:
Rate qr/$search/ m/$search/ qr/$search/ 5.40/s -- -73% m/$search/ 20.1/s 272% --
在装有 Strawberry perl
5.12.1 的 Windows XP 上:
Rate qr/$search/ m/$search/ qr/$search/ 6.42/s -- -66% m/$search/ 18.6/s 190% --
在带有 bleadperl
的 ArchLinux 上:
Rate qr/$search/ m/$search/ qr/$search/ 9.25/s -- -38% m/$search/ 14.8/s 60% --
关于regex - 对 Perl 正则表达式进行基准测试时出现意外的速度行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3889036/