在阅读了关于检查数组中是否存在值的最新Perl问题之后,让我想到了如何执行此操作。我看大多数人的形式推荐grep的选项Perl智能匹配运算符或grep检查数组中是否存在值
if (!grep { $input_day eq $_ } @days) {
say "Grep Invalid Day";
}
然而,当我读到这个问题,我首先通过跃升为智能匹配运营商
unless ($input_day ~~ @days) {
say "Smart Invalid Day";
}
所以这让我不知道是否有任何好处在智能匹配上使用grep,反之亦然。我知道智能匹配只能在更高版本的Perl中使用,因此不适用于5.10.1之前版本的Perl。
我从来没有真正用过Benchmark Perl代码,所以下面的代码是从一个在线例子中编写的。我曾尝试运行200万次智能匹配示例和200万次grep示例并记录时间。
use strict;
use warnings;
use v5.16.2;
use Benchmark;
my $input_day = shift;
my @days = qw /mon tue wed thu fri sat sun/;
my $smart_test_start = new Benchmark();
for(my $x=0; $x<10000000; $x++){
unless ($input_day ~~ @days) {
#here we would execute some code
}
}
my $smart_test_end = new Benchmark();
my $grep_test_start = new Benchmark();
for(my $y=0; $y<10000000; $y++){
if (!grep { $input_day eq $_ } @days) {
#here we would execute some code
}
}
my $grep_test_end = new Benchmark();
my $smart_diff = timediff($smart_test_end, $smart_test_start);
my $grep_diff = timediff($grep_test_end, $grep_test_start);
say "SMART: ", timestr($smart_diff,'all');
say "GREP: ", timestr($grep_diff,'all');
我使用了几个不同的输入。
输入 “星期一”
SMART: 3 wallclock secs (2.75 usr 0.00 sys + 0.00 cusr 0.00 csys = 2.75 CPU)
GREP: 12 wallclock secs (12.02 usr 0.01 sys + 0.00 cusr 0.00 csys = 12.03 CPU)
输入 “周四”
SMART: 6 wallclock secs (5.67 usr 0.00 sys + 0.00 cusr 0.00 csys = 5.67 CPU)
GREP: 11 wallclock secs (11.46 usr 0.01 sys + 0.00 cusr 0.00 csys = 11.47 CPU)
输入 “晒”
SMART: 8 wallclock secs (8.87 usr 0.01 sys + 0.00 cusr 0.00 csys = 8.88 CPU)
GREP: 12 wallclock secs (11.62 usr 0.00 sys + 0.00 cusr 0.00 csys = 11.62 CPU)
输入 “非”
SMART: 9 wallclock secs (8.46 usr 0.00 sys + 0.00 cusr 0.00 csys = 8.46 CPU)
GREP: 11 wallclock secs (11.58 usr 0.13 sys + 0.00 cusr 0.00 csys = 11.71 CPU)
在所有情况下,智能匹配运算符似乎比grep执行得更好。看看结果,我假设在早期使用情况下,这是因为智能匹配一旦发现匹配就会停止,因为在匹配第一个匹配项后,grep将继续检查数组的其余部分。
我再看看其他人推荐使用某些模块找到的第一个实例等
是否有某种原因,人们不建议智能匹配运营商?智能匹配有限制还是不可靠?
你也应该考虑从'['名单:: MoreUtils'] any'(HTTPS ://metacpan.org/pod/List :: MoreUtils) – Borodin