それで、
仕様
何らかの問題があり、それに対する少なくとも 2 つの解決策があるとします。そして、私たちが達成したいのは、それらの有効性を比較することです. これを行う方法?明らかに、最良の答えはdo testsです。そして、言語固有の質問に関しては、より良い方法があるとは思えません (たとえば、「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
];
}
-これは私たちの問題に適合し、比較ベンチマークを行うために使用できます。比較の下では、上記の function を code に使用しX
、次に code に使用でき、その後、 codeはcode よりも高速/低速で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
-つまり、どれだけのメモリを使用するか。「どのくらい」とは、 「関数の実行中の最大メモリ使用量」を意味します。そして、実行時間を測定していたときのように振る舞えないことは明らかです - それ以外の機能については何も知らないので、それはブラックボックスです. 実際には、関数が正常に実行されるかどうかさえ確信できません (たとえば、何らかの方法$x
で$y
内部baz
が 1E6 として割り当てられた場合に何が起こるか想像してみてください)。したがって、コードを関数内にラップするのは得策ではないかもしれません。しかし、コード自体に他の関数/メソッド呼び出しが含まれている場合はどうなるでしょうか?
私のアプローチ
私の現在のアイデアは、各入力コードの行の後にメモリを測定する関数を何らかの方法で作成することです。これは次のようなことを意味します: コードを用意しましょう
$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()
関数に移動して、.. その中で私の分析を繰り返します。等々。 - 第 2 に、前述したように、テストを実行することによってのみ解決できる言語固有の問題がいくつかあります。そういうわけで、時間測定のような自動化された方法を持つことが私の目標です。
また、ガベージ コレクションが有効になっています。私はPHP 5.5を使用しています(これは重要だと思います)
質問
特定の関数のメモリ使用量を効果的に測定するにはどうすればよいでしょうか? PHPで実現できますか?簡単なコード(benchmark
上記の時間測定機能など)で可能でしょうか?