PHP递归和循环的速度测试

本文于 2017-12-05 重新整理.

写了一个可以对 $_GET, $_POST 等输入进行过滤的函数,递归实现如下:

function array_map_recursive($filters, $data)
{
	$result = [];
	foreach ($filters as $filter)
	{
		foreach ($data as $key => $value)
		{
			$result[$key] = is_array($value) 
				? array_map_recursive($filters, $value)
				: call_user_func($filter, $value);
		}
	}
	return $result;
}

后来想想,以前看书的时候经常说递归函数会浪费堆栈空间,甚至会导致堆栈溢出,于是重新用循环实现了这个函数:

function array_map_all($filters, $data)
{
	foreach ($filters as $filter)
	{
		$stack = [];
		$stack[] = &$data;
		while ( ! empty($stack))
		{
			$node = &$stack[count($stack) - 1];

			array_pop($stack);

			if ( ! is_array($node))
			{
				$node = call_user_func($filter, $node);
			}
			else
			{
				foreach ($node as $key => $value)
				{
					if ( ! empty($value))
					{
						$stack[] = &$node[$key];
					}
				}
			}
		}
	}
	return $data;
}

写完哇擦多了这么多行还是递归简洁明了:)

速度如何呢?写个代码测试一下!

$filters = ['trim', 'htmlspecialchars'];
$data = [
	' 5 &',
	[' 3 ', ' 7 '],
	[' 2 ', ' 4 '],
	' 15 ',
	' 4 ',
	['12 ', '  ', ' 3 ', ' 4'],
];

$begin = microtime(true);
for ($i = 0; $i < 10000; $i++)
{
	array_map_recursive($filters, $data);
}
$t1 = microtime(true) - $begin;
echo '递归用时: '.sprintf('%.4f', $t1)."\n";

$begin = microtime(true);
for ($i = 0; $i < 10000; $i++)
{
	array_map_all($filters, $data);
}
$t2 = microtime(true) - $begin;
echo '循环用时: '.sprintf('%.4f', $t2)."\n";

运行结果:
递归用时: 0.4985
循环用时: 0.5489

换个复杂的七维数组,如下:

$data = [
	' 5 &',
	[' 3 ', ' 7 ', [' 55 ', ['    565 ', [' 5445 ', ['da ', [', d '], '3']], 'd d']]],
	[' 2 ', ' 4 '],
	' 15 ',
	' 4 ',
	['12 ', '  ', ' 3 ', ' 4'],
];

运行结果:
递归用时: 5.7484
循环用时: 0.9799

嘿嘿结果不用我说了吧!还是循环好一些,不过实际应用中,是感觉不到太大差别的,毕竟是10000次循环呐!更何况是一个七维数组呢


文章来源于本人博客,发布于 2015-07-05,原文链接:https://imlht.com/archives/56/

posted @ 2023-01-21 13:57  仁扬  阅读(24)  评论(0编辑  收藏  举报