关于 in_array 和 switch 的比较
该文章迁移自作者的旧博客站点。
源地址:http://fenying.blog.163.com/blog/static/102055993201551733611578/。
源地址:http://fenying.blog.163.com/blog/static/102055993201551733611578/。
很多时候会用 in_array 判断一个值是否在允许值内,比如 in_array (‘apple’, $fruits) 就可以判断是否水果。
理论上这一点也可以用 switch 实现,但是问题就在于,switch 并不是可以随意改动的,而数组可以存放到配置文件里。而且另一个问题在于,尽管不如 in_array 方便,可 switch 是语言结构的一部分,性能上绝对比 in_array 高得多。而优化的条件就取决于,两者的性能差异有多大,如果不大,那么用 switch 对 in_array 进行优化毫无意义。
今天被人问到了,索性写一个程序试试两者的性能差异,如下。
<?php
/**
* This scripts is used to compare the speed
* between in_array and switch.
*
* Author: Angus.Fenying
* Date: 2015-06-17
* Blog: http://fenying.blog.163.com
*/
class Test {
public function main(array $args) {
set_time_limit(0);
/* 空白对照,只进行计数计时。*/
$time_blank = [];
for ($i = 0; $i < 10; ++$i)
$time_blank[] = $this->test_blank($i);
$time_blank = array_sum($time_blank) / count($time_blank);
/* 测试当 in_array 命中时的速度 */
$time_in_array_hit = [];
for ($i = 0; $i < 10; ++$i)
$time_in_array_hit[] = $this->test_in_array($i);
$time_in_array_hit = array_sum($time_in_array_hit) / count($time_in_array_hit);
/* 测试当 in_array 未命中时的速度 */
$time_in_array_miss = [];
for ($i = 5; $i < 10; ++$i)
$time_in_array_miss[] = $this->test_in_array($i);
$time_in_array_miss = array_sum($time_in_array_miss) / count($time_in_array_miss);
/* 测试当 switch 命中时的速度 */
$time_switch_hit = [];
for ($i = 0; $i < 10; ++$i)
$time_switch_hit[] = $this->test_switch($i);
$time_switch_hit = array_sum($time_switch_hit) / count($time_switch_hit);
/* 测试当 switch 未命中时的速度 */
$time_switch_miss = [];
for ($i = 5; $i < 10; ++$i)
$time_switch_miss[] = $this->test_switch($i);
$time_switch_miss = array_sum($time_switch_miss) / count($time_switch_miss);
echo '<p>Blank: ', $time_blank, '</p>';
echo '<p>in_array[hit]: ', $time_in_array_hit, '</p>';
echo '<p>in_array[miss]: ', $time_in_array_miss, '</p>';
echo '<p>switch[hit]: ', $time_switch_hit, '</p>';
echo '<p>switch[miss]: ', $time_switch_miss, '</p>';
}
protected function test_blank($g) {
$t0 = microtime(true);
for ($k = 0; $k < 1000000;++$k);
return microtime(true) - $t0;
}
protected function test_in_array($g) {
$t0 = microtime(true);
for ($k = 0; $k < 1000000;++$k)
if (in_array($k, [0,1,2,3,4]));
else;
return microtime(true) - $t0;
}
protected function test_switch($g) {
$t0 = microtime(true);
for ($k = 0; $k < 1000000;++$k)
switch ($g) {
case 0:
case 1:
case 2:
case 3:
case 4:
break;
default:
}
return microtime(true) - $t0;
}
}
也就是进行10次 “100W次 in_array/switch 测试” ,然后求平均用时,个人的机器上测试结果是
- 软件:Windows 8.1 Enterprise Edition / PHP 5.5.15 / Nginx 1.7.2
- 硬件:Intel Core i5-3210M 2.5GHz / 8GB
- 空白测试: 0.068772172927856
- in_array[命中]: 1.4430939435959
- in_array[未命中]: 1.4188071727753
- switch[命中]: 0.24772312641144
- switch[未命中]: 0.28292064666748
可见,switch 的效率大约是 in_array 的 5~6 倍。是否有价值对此进行优化,还请自酌~
comments powered by Disqus