コードの速度をテストしていますか?
-
02-07-2019 - |
質問
私はまったくの初心者ですが、C# で文字列を処理する小さなプログラムを作成していて、いくつかのことを変えるとコードの実行が大幅に高速になることに気付きました。
そこで疑問に思ったのは、コードの実行速度をどのように計測しているのかということです。(無料の)ユーティリティはありますか?System.Timer を使った昔ながらの方法で自分でやりますか?
解決
あなたが説明していることは、パフォーマンスプロファイリングとして知られています。これを行うために利用できるプログラムはたくさんあります。 Jetbrains プロファイラー または アリプロファイラ, ただし、ほとんどの場合、パフォーマンスの測定中にアプリケーションの速度が低下します。
独自のパフォーマンス プロファイリングを手動で実行するには、次を使用できます。 システム.診断.ストップウォッチ あなたが説明したような単純な Console.WriteLine。
また、C# JIT コンパイラーは、呼び出されるタイプと頻度に応じてコードを最適化するため、さまざまなサイズのループや、再帰呼び出しなどのメソッドを試して、何が最適に機能するかを確認してください。
他のヒント
RedGate の ANTS プロファイラー は本当に優れたパフォーマンス プロファイラーです。 JetBrains の dotTrace プロファイラー も素晴らしいです。これらのツールを使用すると、個々の行をドリルダウンできるパフォーマンス メトリクスを確認できます。
ANTS Profiler のスクリーンショット:ANTS http://www.red-gate.com/products/ants_profiler/images/app/timeline_calltree3.gif
単体テスト中に特定のメソッドが特定のパフォーマンスしきい値内に収まるようにしたい場合は、 Stopwatch
クラス メソッドの実行時間をループ内で何度も監視し、平均を計算してから Assert
結果に反して。
注意してください - デバッグではなくリリースでコンパイルするようにしてください。(経験豊富な開発者がこの間違いを犯したのを見てきましたが、忘れがちです)。
あなたが説明しているのは「パフォーマンスチューニング」です。パフォーマンス チューニングについて話す場合、2 つの観点があります。(a) 応答時間 - 特定のリクエスト/プログラムの実行にかかる時間。(b) スループット - 1 秒間に実行できるリクエストの数。通常、「最適化」する場合、つまり不必要な処理を排除すると、応答時間とスループットの両方が向上します。ただし、コード内に待機イベント (Thread.sleep()、I/O 待機など) がある場合、応答時間は影響を受けますが、スループットには影響しません。並列処理 (複数のスレッドの生成) を採用すると、応答時間は向上しますが、スループットは向上しません。通常、サーバー側アプリケーションでは、応答時間とスループットの両方が重要です。デスクトップ アプリケーション (IDE など) の場合、スループットは重要ではなく、応答時間のみが重要です。
「パフォーマンス テスト」によって応答時間を測定できます。すべての主要なトランザクションの応答時間を書き留めるだけです。「負荷テスト」によってスループットを測定できます。サーバー マシンの CPU 使用率が 80 ~ 90% になるように、十分な数のスレッド/クライアントからリクエストを継続的にポンプする必要があります。リクエストをポンプするときは、異なるトランザクション間の比率 (トランザクション ミックスと呼ばれます) を維持する必要があります。たとえば、次のとおりです。予約システムでは、100 件の検索ごとに 10 件の予約が発生します。10件の予約ごとに1件のキャンセルが発生します。
応答時間の調整 (パフォーマンス テスト) が必要なトランザクションを特定した後、プロファイラーを使用してホット スポットを特定できます。応答時間 * トランザクションの割合を比較することで、スループットのホット スポットを特定できます。検索、予約、キャンセルのシナリオで、比率が 89:10:1 であると仮定します。応答時間は0.1秒、10秒、15秒です。検索の負荷-0.1 * .89 = 0.089予約の負荷-10 * .1 = 1キャンセル= 15 * .01 = 0.15ここでのチューニング予約は、スループットに最大の影響をもたらします。また、スレッド ダンプ (Java ベースのアプリケーションの場合) を繰り返し取得することで、スループットのホット スポットを特定することもできます。
プロファイラーを使用します。
- アリ(http://www.red-gate.com/Products/ants_profiler/index.htm)
- ドットトレース (http://www.jetbrains.com/profiler/)
1 つの特定のメソッドのみの時間を計測する必要がある場合は、Stopwatch クラスが適している可能性があります。
私は次のことを行っています。1) ティックを使用します (例:VB.Net Now.ticks) を使用して、現在時刻を測定します。終了したティック値から開始ティックを減算し、TimeSpan.TicksPerSecond で割って、かかった秒数を取得します。2) UI 操作 (console.writeline など) を避けます。3) 使用状況や OS の変数をできる限り考慮するために、かなりのループ (100,000 回の反復など) でコードを実行します。
StopWatch クラスを使用してメソッドの時間を測定できます。コードを jit する必要があるため、初回は時間がかかることが多いことに注意してください。
一部のパフォーマンス分析ニーズに対応できるネイティブ .NET オプション (ソフトウェア開発者向けチーム版) があります。2005 .NET IDE メニューから、[ツール] -> [パフォーマンス ツール] -> [パフォーマンス ウィザード...] を選択します。
[Team Edition が必要であるという GSS の考えはおそらく正しいです]
これはコード速度をテストするための簡単な例です。お役に立てれば幸いです
class Program {
static void Main(string[] args) {
const int steps = 10000;
Stopwatch sw = new Stopwatch();
ArrayList list1 = new ArrayList();
sw.Start();
for(int i = 0; i < steps; i++) {
list1.Add(i);
}
sw.Stop();
Console.WriteLine("ArrayList:\tMilliseconds = {0},\tTicks = {1}", sw.ElapsedMilliseconds, sw.ElapsedTicks);
MyList list2 = new MyList();
sw.Start();
for(int i = 0; i < steps; i++) {
list2.Add(i);
}
sw.Stop();
Console.WriteLine("MyList: \tMilliseconds = {0},\tTicks = {1}", sw.ElapsedMilliseconds, sw.ElapsedTicks);