所以,
细节
让我们假设我们有一些问题,并且至少有两个解决方案。而我们想要实现的 - 是比较他们的有效性。这个怎么做?显然,最好的答案是:做测试。而且我怀疑对于特定于语言的问题(例如“什么对 PHP 来说更快:echo 'foo', 'bar'
或echo('foo'.'bar')
”)有更好的方法。
好的,现在我们假设如果我们要测试一些代码,就等于测试一些功能。为什么?因为我们可以将该代码包装为函数并将其上下文(如果有)作为参数传递。因此,我们所需要的只是拥有,例如,一些可以做所有事情的基准函数。这是一个非常简单的:
function benchmark(callable $function, $args=null, $count=1)
{
$time = microtime(1);
for($i=0; $i<$count; $i++)
{
$result = is_array($args)?
call_user_func_array($function, $args):
call_user_func_array($function);
}
return [
'total_time' => microtime(1) - $time,
'average_time' => (microtime(1) - $time)/$count,
'count' => $count
];
}
- 这将适合我们的问题,可用于进行比较基准测试。在比较下,我的意思是我们可以将上面的函数用于代码X
,然后用于代码,然后Y
,我们可以说代码X
比Z%
代码快/慢Y
。
问题
好的,所以我们可以很容易地测量时间。但是内存呢?我们之前的假设“如果我们要测试一些代码,它就等于测试一些功能”在这里似乎不成立。为什么?因为 - 从形式上看是正确的,但是如果我们将代码隐藏在函数中,那之后我们将永远无法测量内存。例子:
function foo($x, $y)
{
$bar = array_fill(0, $y, str_repeat('bar', $x));
//do stuff
}
function baz($n)
{
//do stuff, resulting in $x, $y
$bee = foo($x, $y);
//do other stuff
}
- 我们想要测试baz
- 即它将使用多少内存。“多少”是指“函数执行期间的最大内存使用量”。很明显,我们不能像测量执行时间时那样行事——因为我们对它之外的功能一无所知——它是一个黑匣子。如果事实上,我们甚至无法确定该函数是否会成功执行(例如,想象一下如果以某种方式将内部分配为 1E6 会发生$x
什么$y
)baz
。因此,将我们的代码包装在函数中可能不是一个好主意。但是如果代码本身包含其他函数/方法调用呢?
我的方法
我目前的想法是以某种方式创建一个函数,它将在每个输入代码的 line 之后测量内存。这意味着这样的事情:让我们有代码
$x = foo();
echo($x);
$y = bar();
- 在做了一些事情之后,测量功能会做:
$memory = memory_get_usage();
$max = 0;
$x = foo();//line 1 of code
$memory = memory_get_usage()-$memory;
$max = $memory>$max:$memory:$max;
$memory = memory_get_usage();
echo($x);//second line of code
$memory = memory_get_usage()-$memory;
$max = $memory>$max:$memory:$max;
$memory = memory_get_usage();
$y = bar();//third line of code
$memory = memory_get_usage()-$memory;
$max = $memory>$max:$memory:$max;
$memory = memory_get_usage();
//our result is $max
- 但这看起来很奇怪,而且它也没有回答一个问题 - 如何测量函数内存使用情况。
用例
用例:在大多数情况下,复杂性理论至少可以big-O
为某些代码提供估计。但:
- 首先,代码可能很大——我想尽可能避免手动分析。这就是我目前的想法不好的原因:它可以应用,是的,但它仍然需要手动处理代码。而且,为了更深入地了解代码结构,我需要递归地应用它:例如,在将它应用到顶层之后,我发现某些
foo()
函数占用了太多内存。我将要做的?是的,去这个foo()
函数,然后……在里面重复我的分析。等等。 - 第二 - 正如我所提到的,有一些特定于语言的事情只能通过测试来解决。这就是为什么我的目标是有一些像时间测量这样的自动方式。
此外,垃圾收集已启用。我正在使用 PHP 5.5(我相信这很重要)
问题
我们如何有效地测量某些功能的内存使用情况?它可以在PHP中实现吗?是否可以使用一些简单的代码(例如benchmark
上面的时间测量功能)?