1

かなり複雑な F# アプリケーションがあり、F# スクリプトを使用して#timeディレクティブを使用してそのパフォーマンスをチェックしています。コードを変更した後にスクリプトを実行して、パフォーマンスを追跡し、速度やメモリの問題が発生しないようにするという考え方です。

私が受け取ったレポートは次のようなものでした。

Real: 00:00:02.908, CPU: 00:00:02.948, GC gen0: 237, gen1: 3, gen2: 1

しかし、最後の変更の後、私はこれを取得します:

Real: 00:00:03.058, CPU: 00:00:03.057, GC gen0: 262, gen1: 262, gen2: 0

そして、何が起こっているのかを理解するのに苦労しています。

ジェネレーション 1 のガベージ コレクションが増えるということは、ジェネレーション 0 のガベージ コレクションで生き残る長寿命のオブジェクトが増えることを意味します (?)。しかし、なぜ 3 から 262 に突然ジャンプするのでしょうか? また、ジェネレーション 0 とジェネレーション 1 のガベージ コレクションの数が同じなのはなぜですか? 何らかの理由でコードが変更された後、さらに長寿命のオブジェクトがある場合、次のようなものを期待していました。

Real: 00:00:02.908, CPU: 00:00:02.948, GC gen0: 212, gen1: 54, gen2: 1

つまり、ガベージ コレクションされたオブジェクトの総数は似ていますが、ジェネレーション 1 の方が多くなっています。

それとも、これらの数字を完全に誤解していますか (ドキュメントに説明がありませんでした)。

アップデート

コメントで指摘されているように、私は数字を完全に誤解していました。オブジェクトの数ではなく、世代ごとに実行されたガベージ コレクションの数です。

私はさらに困惑していると言いました.私のアプリケーションは、ジェネレーション0のガベージコレクションがジェネレーション1のガベージコレクションもトリガーするような状態にメモリを置いたようで、この状態がどうなるか想像できません. このような動作を再現するために、さまざまなテスト プログラムを試してみましたが、うまくいきませんでした。

コメントとパッドの回答で提案されているように、プロファイラーを試す必要があります。

更新 2

コメントで提案されているように、CLR プロファイラーを試しました。そのために、F# スクリプトをプログラムに変換し、プロファイラーから実行しました。

#time私が受け取るレポートは、ガベージ コレクションとはまったく異なります。

  • ジェネレーション 0: 279
  • 世代 1: 5
  • 世代 2: 2。

ミステリー - スタンドアロン プログラムと比較して FSI.exe を使用することのストレージの副作用? バグ#time

4

1 に答える 1

2

.NET GC は 3 世代の GC です。John Palmer が指摘したように、最後の 3 つの数字は、これらの世代で実行されたコレクションの数です。GC は各ガベージ コレクション プロセスでこれらの未使用のオブジェクトを何度もマークする必要があるため、大きな数値はパフォーマンスの低下を示しますgen1gen2.NET GC の詳細な紹介については、この素晴らしい記事をご覧ください。

以下にいくつかの提案を示します。

  1. 最初のセッションで使用されていないオブジェクトが 2 番目のセッションに影響を与えないように、2 つの測定の間に必ず「セッションをリセット」してください。
  2. 測定する 3 つの大きな入力を見つけます。これら 2 つのレポートの実行時間は似ていますが、最初のアプローチの方がスケーラブルであると思います。スケーラビリティをテストするために複数の入力サイズがあると便利です。
  3. 異常なセッションを観察するだけかもしれないので、パターンを記録するために数回測定してください。
  4. 疑わしい場合は、Visual Studio で全範囲のプロファイリングを実行してください。彼らのレポートは、パフォーマンス予測に関してはるかに包括的で信頼性があります。
于 2012-09-17T05:26:47.643 に答える