私はこの質問を見てきましたが、多少似ています。アプリケーションのパフォーマンスに影響を与える大きな要因であるかどうかを知りたいです。これが私のシナリオです。
行ごとに上から下に読み取られるスプレッドシートから何千ものデータをアップロードできるこの Java Web アプリケーションがあります。System.out.println()
アプリケーションが現在読んでいる行をサーバー側に表示するために
使用しています。
- ログ ファイルの作成については承知しています。実際、ログ ファイルを作成し、同時にサーバーのプロンプトにログを表示しています。
現在のデータをプロンプトに出力する他の方法はありますか?
6 に答える
私は最近、大きな(1〜1.5GB)テキストファイルの(読み取りと)書き込みをテストしていましたが、次のことがわかりました:
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(java.io.FileDescriptor.out), "UTF-8"), 512));
out.println(yourString);
//...
out.flush();
実際、よりもほぼ250%高速です。
System.out.println(yourString);
テスト プログラムは、最初に約 1 GB のデータを読み取り、少し処理して、わずかに異なる形式で出力しました。
テスト結果 (Macbook Pro で、同じディスクを使用して SSD の読み取りと書き込みを行う場合):
- データ出力からシステム出力へ > output.txt => 1分32秒
- Java でファイルに書き込まれたデータ => 37 秒
- data-write-to-buffered-writer-stdout > output.txt => 36 秒
256 ~ 10k のサイズの複数のバッファを試してみましたが、問題にはならなかったようです。
そのため、Java を使用して UNIX コマンド ライン ツールを作成し、出力を別の場所に送信またはパイプする場合は、System.out を直接使用しないでください。
アプリケーションのパフォーマンスに影響を与える可能性があります。大きさは、実行しているハードウェアの種類とホストの負荷によって異なります。
これがパフォーマンスの観点から解釈できるいくつかのポイント:
-> Rocket boy が述べたように、println は同期されます。つまり、オブジェクト ヘッダーのロック オーバーヘッドが発生し、設計によってはスレッドのボトルネックが発生する可能性があります。
->コンソールでの印刷にはカーネル時間が必要です。カーネル時間は、CPUがユーザーモードで実行されないことを意味します。これは、基本的に、CPUがアプリケーションコードではなくカーネルコードの実行でビジーになることを意味します。
-> すでにこれをログに記録している場合は、I/O のためのカーネル時間が余分にあることを意味し、プラットフォームが非同期 I/O をサポートしていない場合は、CPU がビジー待機で停止する可能性があることを意味します。
これを実際に試してベンチマークし、自分で検証することができます。
たとえば、非常に高速な I/O、おそらく専用の巨大なマシン、アプリケーション設計がそのコンソール印刷でマルチスレッド化されない場合の JVM オプションの偏ったロックなど、これを回避する方法があります。
パフォーマンスに関するすべてのことと同様に、それはすべてハードウェアと優先順位に依存します。
System.out.println()
同期されます。
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
複数のスレッドが書き込みを行うと、パフォーマンスが低下します。
System.out.println は、ほとんどの遅い操作に比べて非常に遅いです。これは、他の IO 操作よりも多くの作業をマシンに配置するためです (そして、シングル スレッドです)。
出力をファイルに書き込み、このファイルの出力を書き込むことをお勧めしtail
ます。この方法でも、出力は遅くなりますが、Web サービスの速度がそれほど低下することはありません。