Ste*_*las 24 perl performance string-matching
鉴于两个字符串变量$string和$needlein perl,什么是检查是否$string开始的最有效方法$needle.
$string =~ /^\Q$needle\E/ 是我能想到的最接近的匹配,它做了所需要的但是效率最低(到目前为止)我尝试过的解决方案.index($string, $needle) == 0对某些值有效并且相对有效$string,$needle但不必要地在其他位置搜索针(如果在开始时没有找到).substr($string, 0, length($needle)) eq $needle 应该是非常简单和有效的,但在我的几个测试中,大多数测试并不比前一个测试更有效.是否有规范的方法可以做到这一点perl,我不知道或以任何方式优化任何上述解决方案?
(在我的特定用例中,$string并且$needle在每次运行中将会有所不同,因此预编译正则表达式不是一种选择).
如何衡量给定解决方案性能的示例(此处来自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"
Run Code Online (Sandbox Code Playgroud)
使用这些值,使用perl 5.14.2 index()比substr()+eq使用此系统更好,但是:
string="aaaaabaaaaabaaaaabaaaaabaaaaabaaaaab" needle="aaaaaa"
Run Code Online (Sandbox Code Playgroud)
那是相反的.
Sue*_*mme 19
这有多重要,真的吗?我做了很多基准测试,index每次迭代的平均方法为0.68微秒; 正则表达式方法1.14μs; 该substr方法0.16μs.即使是我最糟糕的场景(2250-char字符串相同),index耗时2.4μs,正则表达式耗时5.7μs,substr耗时0.5μs.
我的建议是编写一个库例程:
sub begins_with
{
return substr($_[0], 0, length($_[1])) eq $_[1];
}
Run Code Online (Sandbox Code Playgroud)
并将优化工作重点放在其他地方
更新:基于对上述"最坏情况"情况的批评,我运行了一组新的基准测试,其中包含一个20,000字符随机生成的字符串,将其与自身进行比较,并与仅在最后一个字节中不同的字符串进行比较.
对于如此长的字符串,正则表达式解决方案是迄今为止最差的(20,000字符的正则表达式是地狱):匹配成功为105μs,匹配失败为100μs.
在index和substr解决方案仍然相当快.index成功/失败substr为11.83μs/11.86μs ,为4.09μs/4.15μs.将代码移动到单独的函数中添加约0.222±0.05μs.
基准代码见:http://codepaste.net/2k1y8e
我不知道@Sphane的数据的特征,但我的建议是立场.
另一个选择是将rindex位置设置为0,这意味着“从位置<= 0开始,在$ str中获取$ substr的索引”,即它仅检查$ substr是否为$ str的前缀:
> rindex "abc", "a", 0
0
> rindex "abc", "b", 0
-1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25508 次 |
| 最近记录: |