这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
PHP 首要说的就是性能方面的提升。对于 in_array()一直诟病很多,至于性能有多差,先简单测试一下,看看数据。
实例测试
测试程序如下:
1 | php复制代码<?php |
测试结果
in_array 方式
- 字符型字符串
1 | arduino复制代码// 3k 消耗时间:1.0687351226807 |
- int 型字符串
1 | arduino复制代码// 3k 消耗时间:1.0500609874725 |
isset 方式
- 字符型字符串
1 | arduino复制代码// 3k 消耗时间:0.00010299682617188 |
- int 型字符串
1 | arduino复制代码// 3k 消耗时间:0.00010108947753906 |
结合上面测试数据,两种方式的性能差距还是挺明显的。
接着,我们利用 ltrace 来跟踪进程调用库函数的情况:
1 | shell复制代码$ ltrace -c /usr/local/php/bin/php test.php |
看到库函数__strtol_internal 的调用非常之频繁,这个库函数__strtol_internal 是原来是 strtol 的别名,简单的说就是把字符串转换成长整形,可以推测 PHP 引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:
1 | shell复制代码$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php |
可以轻松抓到大量下图这样的调用,到此,问题找到了,in_array 这种松比较,会将两个字符型数字串先转换为长整型再进行比较,却不知性能就耗在这上面了。
知道了症结所在,我们解决的办法就很多了,最简单的就是为 in_array 加第三个参数为 true,即变为严格比较,同时还要比较类型,这样避免了 PHP 自作聪明的转换类型,跑起来果然快多了,代码如下:
1 | bash复制代码in_array(search,array,type) |
总结
总结一下,大数组的查询,用 in_array 函数是个糟糕的选择。应该尽量用 isset 函数来替代 。in_array 函数的复杂度是 O(n),而 isset 函数的复杂度是 O(1)。
- END -
作者:架构精进之路,十年研发风雨路,大厂架构师,CSDN 博客专家,专注架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一起成长。
关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。
Thanks for reading!
本文转载自: 掘金