16

私たちはかなり奇妙な問題IMOに出くわしました。私たちのクライアントは、アプリケーションがファイルからデータをインポートして処理する速度について不満を持っています[ファイルサイズ1kB cca、通常の状態でファイルをインポートするのに必要な時間は、全体的なワークロードに応じて4〜10秒です。はい、たくさんあります] .. ..

そこで調査を開始しましたが、まったく予期しないことが起こりました。コードの特定の部分にデバッグログ出力を挿入した後[ロジックに影響を与えない]、全体的なワークロードに応じて、インポートが大幅に高速化されました:300ms〜2200ms/file。

使用言語:Java

私のステーションのJDK6_34[同僚が使用しているバージョンがわからない]

私はコードを調べました...何度も。異常なことは何もありません。すべてスレッドで実行されますが、このスレッドには、同じジョブを実行したり、同じファイルにアクセスしたりする競合他社はありません。

この状況は誰にでもなじみがありますか?

PS:この質問がここにあることを願っています。そうでない場合は、心からお詫び申し上げます。

編集:

ロギングに関しては、log4jを使用します。

OS:WindowsXP/私のマシン。1人の同僚は同じものを持っており、もう1人はWin7/を使用しています。

CPU:E7500 @ 2.93 GHz

RAM:2 GB DDR2

他の1台のマシンは基本的に同じです。3番目の構成は新しいものであり、私のワークステーションではないため、私にはわかりません。

私の状況では、ファイルはすべてローカルHDDとの間でロード/保存されます。

私が最も懸念しているのは、ソースがないプラットフォームを使用していることです。ライセンスの支払いは済んでいますが、ソースは支払っていないためです>。<

4

5 に答える 5

5

私の理論では、ロギングを追加すると、アプリケーションのスレッド スケジューリング パターンが変化するということです。

通常、これは問題になりません。しかし、アプリケーションの根本的な問題がスレッド スケジューリングに関連するものである場合、ログ記録によって観察された動作が変化することは驚くべきことではありません。

Thread.sleep(...)呼び出し、Thread.yield()呼び出し、コードがポーリングしている場所などを探して、コードベースの関連部分を監査することをお勧めします。また、これがサードパーティのライブラリ コードで発生している可能性があることも考慮してください。

@OldCurmudgeon の回答には、探しているものの 2 つの単純なバージョンが含まれています。ゼロよりも大幅に大きい場合よりはましですが、使用してsleep(0)も無駄です。sleep(N)N

于 2012-09-07T23:08:55.763 に答える
4

この種の状況で、私が行ったことは、アプリケーションの重要な部分 (たとえば 5 ~ 10 ステージ) にトレース タイミングを配置し、どの部分に最も時間がかかっているかを確認することでした。あなたの場合、どの段階が高速化するかを確認できます。より高速なステージが 1 つだけあると思われます。その場合は、そのステージにより多くのタイミングを配置し、最も違いが見られるコードに絞り込むことができます。

過去に奇妙な遅延の増加が見られたのは、DNS ルックアップなどのネットワーク呼び出しが原因でした。ファイルを処理するとき、外部アプリケーション/ネットワーク サービスにアクセスしていますか?

于 2012-09-08T06:57:10.420 に答える
4

使用しているマシンで、顧客の元の問題を再現できましたか (つまり、ファイルをプルして、言及したように 4 ~ 10 秒かかるようにすることができましたか?)

そうでない場合は、log4j に特にクレジットを与えるにはあまりにも多くの要因が関係しています。私はこれについてウィルフと一緒です。ログを追加することで確実にコードの速度を向上させる方法はありません...少なくとも、私が思いつく方法はありません。

問題を再現でき、ログを追加し、同じハードウェア、同じロジック、同じファイルを使用して速度が大幅に向上した場合、あなたは公式に私の心を吹き飛ばしました.

于 2012-09-07T23:03:02.883 に答える
3

ロギングを追加すると、ロジックに同期ポイントが追加されます。おそらく、あなたが見ているのは、これの (奇妙な) 副作用です。

于 2012-09-07T23:01:50.427 に答える
2

スピンループを探しています。

コード (または基礎となるフレームワーク) のどこかに、次のようなコードがあります。

while (!ready()) {
  // Do next to nothing.
}

またはそれに要約される何か。

基本的に、ループが非常に速く回転しているため、待機中のリソースが使用可能になるのに十分な時間がありません。通常、異常に高い CPU 使用率も表示されます。

ロギングによってループが遅くなるため、状態が緩和され、リソースの準備が整います。

次のように変更する必要があります。

while (!ready()) {
  Thread.currentThread().sleep(0);
}

または、理想的には、適切なブロック メカニズムを使用します。

于 2012-09-07T23:47:19.497 に答える