给定perl中的两个字符串变量$string和$needle,检查$string是否以$needle开头的最有效方法是什么?
$string =~ /^\Q$needle\E/是我能想到的最接近的匹配项,它实现了所需的功能,但在我使用的解决方案中(到目前为止)效率最低,对于$string和$needle的某些值来说,它是相对有效的,但不必要地在其他位置搜索指针(如果在start).substr($string, 0, length($needle)) eq $needle中找不到,应该是非常简单和有效的,但在我为数不多的几个测试中的大多数情况下,效率并不比前面的那个高。在perl中,有没有一种我不知道的规范方法可以做到这一点,或者有什么方法可以优化上面提到的任何解决方案?
(在我的特定用例中,$string和$needle在每次运行时都是不同的,所以不能预编译regexp )。
如何测量给定解决方案的性能的示例(此处来自POSIX sh):
string='somewhat not so longish string' needle='somew'
time perl -e '
($n,$string,$needle) = @ARGV;
for ($i=0;$i<$n;$i++) {
index($string, $needle) == 0
}' 10000000 "$string" "$needle"在使用这些值的情况下,index()在使用Perl5.14.2的系统上的性能优于substr()+eq,但在以下情况下:
string="aaaaabaaaaabaaaaabaaaaabaaaaabaaaaab" needle="aaaaaa"这是相反的。
发布于 2019-04-01 20:24:33
rindex $string, $substring, 0在位置<=0处的$string中搜索$substring,这仅在$substring是$string的前缀时才可能。示例:
> rindex "abc", "a", 0
0
> rindex "abc", "b", 0
-1发布于 2015-07-30 22:33:17
这到底有多重要?我做了许多基准测试,index方法每次迭代的平均时间为0.68微秒;正则表达式方法为1.14μs;substr方法为0.16μs。即使在我最坏的情况下(2250个字符的字符串相等),substr花费2.4μs,正则表达式花费5.7μs,而index花费0.5μs。
我的建议是写一个库例程:
sub begins_with
{
return substr($_[0], 0, length($_[1])) eq $_[1];
}并将您的优化工作集中在其他地方。
更新:基于对我上面描述的“最坏情况”的批评,我运行了一组新的基准测试,使用一个20,000个字符的随机生成的字符串,将其与自身以及仅在最后一个字节中不同的字符串进行比较。
对于如此长的字符串,正则表达式的解决方案到目前为止是最差的( 20,000个字符的正则表达式简直是地狱):匹配成功时为105μ,匹配失败时为100μ。
index和substr解决方案仍然相当快。对于成功/失败,index为11.83μs / 11.86μs,substr为4.09μs / 4.15μs。将代码移到单独的函数中增加了大约0.222±0.05μs。
基准测试代码请访问:http://codepaste.net/2k1y8e
我不知道@Stephane的数据的特征,但我的建议是成立的。
https://stackoverflow.com/questions/31724503
复制相似问题