PHP 里实现『是否由某字符串开头』最快的方式

最近在做开源项目 php-m3u8 的时候,为了提高解析 m3u8 文件内容的速度,需要实现『字符串是否是另外某个字符串的开头』的需求。不过在 PHP 里实现这个需求可以实现的方法实在是太多了,所以我这里做了一个测试,列出各种实现方式的速度数据,以供参考。

测试结果大家可以自行测试,总之结果是令我感到意外的。我觉得这个需求用 strncmp 来做,理论上应该是最快的,结果 strncmp 居然输给了 strpos,而 substr 和 strstr 也没 strpos 快也是挺意外……正则是 PHP 内置函数实现 startsWith 的最后一名,所以从性能考虑如果可以用别的方式代替正则,就尽量别用正则。

最后自己写的函数…… 实在惨不忍睹,所以能用 PHP 内置的函数就请尽量用吧。

所消耗时间排名:strpos ~= strrpos < substr < strstr < strncmp < preg_match < 自己实现的函数。

2017-11-27 补充:如果被测试的字符串长度非常的长,比如 2KB 以上,那么测试的情况又有点不一样了,大家可以修改上面的代码自己在机器上跑一下。总之我这边,如果是最坏情况,也就是被测试字符串根本就不包含测试字符串,strpos 的速度会变得非常的慢,而且慢到连跟自己写的函数都不是一个数量级的(之前我就怀疑过这种情况理论上来说 strpos 会慢,但当时被测试的字符串可能还是不够长,感觉 strpos 表现还是可以……)。所以不管从理论上还是实践得出的结论,在被测试字符串是超长字符串并且在最坏状况下所耗时:strrpos < substr < strncmp < preg_match < custom < (从这开始已经不属于一个数量级)strpos < strstr

当然 strrpos 之所以还那么快肯定也得益于他第三个参数的帮助(详情请见上面的代码)

2017-12-15 补充:今天试验了 mb_* 系列函数做了同样的测试,结果真的是非常的惊人……附上 stackoverflow 的一篇问答

wx pay

CC BY-NC-ND 4.0 PHP 里实现『是否由某字符串开头』最快的方式 by Chrisyue's Blog is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

发表评论

电子邮件地址不会被公开。

+ twenty one = twenty three