コードの時間/空間の複雑さを検証するために単体テストを使用する人はいますか?
4 に答える
それはあなたが持ち出す完全に良い点です。確かにこれには単体テストを使用します。
単体テストは、主にコードの結果をテストする「方法」です。本来の動作をするかどうか、失敗させたいときに失敗するかどうかをテストします。
時間と空間は非常に重要な 2 つの変数であり、高速でスペースのコストが低いことを「望む」かもしれませんが、プログラムは実際には逆のことを行います。バグが発生すると、バグを見つけて解決するための単体テストが行われます。彼ら。
ユニットテストの擬似コード 時間がかかるので、これを解決する方法を知っているかもしれませんが、これはかなり良いテスト方法です:
Unit_Test_To_See_If_X_Takes_More_Than_Y_Seconds(int max_milli_seconds)
{
int current_millis = getMillis();
do_operations_on_objects_and_functions();
int millis_after_executions = getMillis();
int elapes_millis = millis_after_execution - current_millis;
if ( elapsed_millis > max_milli_seconds )
Assert(ERROR);
}
また、考えてみると、テストが多すぎることはありますか? いいえ、できません。「ばかげた」ことをテストしても、すべての結果をテストするのは良いことです.またはあなたはそれをテストしませんでしたか?:)
考えられる解決策は、Filip の関数を 1 回繰り返し、次に 100 回、次に 1000 回、次に 10000 回 (など) でテストし、結果をグラフにプロットして時間の複雑さを決定することです。または、数学を使用して、各実行間の最大因子差を導き出します。ただし、スペースをテストする方法はわかりません。
最高の係数(N ^ 2など)を導出してそれと比較する既存のアルゴリズムがない限り、出力が単純な合格または不合格になるとは思いません。
アルゴリズムを調整していたときに、同様の問題が発生しました。私がしたことは、それをループしてから、ループの数と Big-O の値で割ることでした。そして、これを「q」または「品質値」と呼びました。興味深いことに、値は予想どおりほぼ一定であり、不適切なパラメーターの場合は少し高くなりました。ポイントは、big-O の定義を見ると、主要な計算のほかに「支配的でない」計算の測定値が得られることです。多くの場合、それらは一定であるか、複雑さが低くなっています。私の場合、それは少し直線的でしたが、まだ何も考えていませんでした.
私の提案は、そのような品質値を計算することです。次に、複雑さの仮定を破る最後の変更の副作用を示す突然の上昇があるかどうかを確認できます。
時間の側面は Filip と Josh の回答で十分にカバーされていますが、問題のコードは完了時に使用したメモリとリソースを解放する可能性があるため、スペースの問題はより複雑です。したがって、スペースの複雑さを判断するために、単体テスト自体は特に有用ではないと思います。プローブ、またはテスト対象のクーデと非同期で実行される他のモニターのいずれかが必要になります。
テスト対象のコードにその場でのログ/トレースを提供することが最も簡単な解決策であり、リリースビルドから削除される可能性があると思います。