关于 in_array 和 switch 的比较
该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/post/2015/06/17/performance-between-in-array-and-switch-in-php/
很多时候会用 in_array 判断一个值是否在允许值内,比如 in_array (‘apple’, $fruits) 就可以判断是否水果。
理论上这一点也可以用 switch 实现,但是问题就在于,switch 并不是可以随意改动的,而数组可以存放到配置文件里。而且另一个问题在于,尽管不如 in_array 方便,可 switch 是语言结构的一部分,性能上绝对比 in_array 高得多。而优化的条件就取决于,两者的性能差异有多大,如果不大,那么用 switch 对 in_array 进行优化毫无意义。
今天被人问到了,索性写一个程序试试两者的性能差异,如下。
1<?php
2/**
3 * This scripts is used to compare the speed
4 * between in_array and switch.
5 *
6 * Author: Angus.Fenying
7 * Date: 2015-06-17
8 * Blog: http://fenying.blog.163.com
9 */
10class Test {
11
12 public function main(array $args) {
13 set_time_limit(0);
14
15 /* 空白对照,只进行计数计时。*/
16
17 $time_blank = [];
18 for ($i = 0; $i < 10; ++$i)
19 $time_blank[] = $this->test_blank($i);
20 $time_blank = array_sum($time_blank) / count($time_blank);
21
22 /* 测试当 in_array 命中时的速度 */
23
24 $time_in_array_hit = [];
25 for ($i = 0; $i < 10; ++$i)
26 $time_in_array_hit[] = $this->test_in_array($i);
27 $time_in_array_hit = array_sum($time_in_array_hit) / count($time_in_array_hit);
28
29 /* 测试当 in_array 未命中时的速度 */
30
31 $time_in_array_miss = [];
32 for ($i = 5; $i < 10; ++$i)
33 $time_in_array_miss[] = $this->test_in_array($i);
34 $time_in_array_miss = array_sum($time_in_array_miss) / count($time_in_array_miss);
35
36 /* 测试当 switch 命中时的速度 */
37
38 $time_switch_hit = [];
39 for ($i = 0; $i < 10; ++$i)
40 $time_switch_hit[] = $this->test_switch($i);
41 $time_switch_hit = array_sum($time_switch_hit) / count($time_switch_hit);
42
43 /* 测试当 switch 未命中时的速度 */
44
45 $time_switch_miss = [];
46 for ($i = 5; $i < 10; ++$i)
47 $time_switch_miss[] = $this->test_switch($i);
48 $time_switch_miss = array_sum($time_switch_miss) / count($time_switch_miss);
49
50 echo '<p>Blank: ', $time_blank, '</p>';
51 echo '<p>in_array[hit]: ', $time_in_array_hit, '</p>';
52 echo '<p>in_array[miss]: ', $time_in_array_miss, '</p>';
53 echo '<p>switch[hit]: ', $time_switch_hit, '</p>';
54 echo '<p>switch[miss]: ', $time_switch_miss, '</p>';
55 }
56
57 protected function test_blank($g) {
58 $t0 = microtime(true);
59 for ($k = 0; $k < 1000000;++$k);
60 return microtime(true) - $t0;
61 }
62
63 protected function test_in_array($g) {
64 $t0 = microtime(true);
65 for ($k = 0; $k < 1000000;++$k)
66 if (in_array($k, [0,1,2,3,4]));
67 else;
68
69 return microtime(true) - $t0;
70 }
71
72 protected function test_switch($g) {
73 $t0 = microtime(true);
74 for ($k = 0; $k < 1000000;++$k)
75 switch ($g) {
76 case 0:
77 case 1:
78 case 2:
79 case 3:
80 case 4:
81 break;
82 default:
83 }
84
85 return microtime(true) - $t0;
86 }
87}
也就是进行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 的 56 倍。是否有价值对此进行优化,还请自酌
comments powered by Disqus