Fenying

Angus’ Home.


17 Jun 2015

关于 in_array 和 switch 的比较

该文章迁移自作者的旧博客站点。
源地址: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 倍。是否有价值对此进行优化,还请自酌~

该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/post/2015/06/17/performance-between-in-array-and-switch-in-php/

comments powered by Disqus