Javaパフォーマンス最適化:コードを遅くする8つのアンチパターン

アンチパターン修正によるパフォーマンス改善
Jonathan Vogelが構築したJava注文処理アプリケーションは、当初1,198msの経過時間、1秒あたり85,000件の注文処理、1GB強のヒープ使用量、19回のGCポーズでした。アーキテクチャ変更やJDKアップデートなしで8つのアンチパターンを修正した後、パフォーマンスは239msの経過時間、1秒あたり419,000件の注文処理、139MBのヒープ使用量、4回のGCポーズに改善しました。これは、5倍のスループット、87%のヒープ使用量削減、79%のGCポーズ削減を表しています。
修正すべき8つのJavaパフォーマンスアンチパターン
- ループ内での文字列連結 - 不変性によるO(n²)のコピー
- ループ内でのO(n²)ストリーム反復 - 要素ごとに全リストをストリーミング
- ホットパスでのString.format() - 最も遅い文字列ビルダー、呼び出しごとにフォーマットを解析
- ホットパスでのオートボクシング - 数百万の使い捨てラッパーオブジェクト
- 制御フローのための例外 - fillInStackTrace()がコールスタック全体を走査
- 範囲が広すぎる同期 - 1つのロックがボトルネックになる
- 再利用可能なオブジェクトの再作成 - 呼び出しごとのObjectMapper、DateTimeFormatter、Gson
- 仮想スレッドのピン止め(JDK 21-23) - synchronized + ブロッキングI/Oがキャリアをピン止め
詳細な例と修正方法
1. ループ内での文字列連結
問題のあるコード:
String report = "";
for (String line : logLines) {
report = report + line + "\n";
}これは文字列の不変性によりO(n²)のコピーを生成します。BellSoft JMHベンチマークでは、nが4倍になると、ループ連結は7倍以上遅くなることが示されています。
修正:
StringBuilder sb = new StringBuilder();
for (String line : logLines) {
sb.append(line).append("\n");
}
String report = sb.toString();注: JDK 9以降、コンパイラは「Order: " + id + " total: " + amountのような単一行の連結を最適化しますが、この最適化はループ内には適用されません。
2. ループ内でのストリームによる偶発的なO(n²)
問題のあるコード:
for (Order order : orders) {
int hour = order.timestamp().atZone(ZoneId.systemDefault()).getHour();
long countForHour = orders.stream()
.filter(o -> o.timestamp().atZone(ZoneId.systemDefault()).getHour() == hour)
.count();
ordersByHour.put(hour, countForHour);
}このパターンは、JFR記録のCPUスタックサンプルの約71%を占めていました。10,000件の注文では、単一パスではなく1億回の比較を実行します。
修正:
for (Order order : orders) {
int hour = order.timestamp().atZone(ZoneId.systemDefault()).getHour();
ordersByHour.merge(hour, 1L, Long::sum);
}これは1パスでO(n)のパフォーマンスを提供します。単一のストリームパイプラインでCollectors.groupingBy(... Collectors.counting())を使用することもできます。
この記事は3部構成のJavaパフォーマンス最適化シリーズの第1部であり、第2部と第3部は近日公開予定です。第2部では、フレームグラフや実際にホットだったメソッドを含む、これらの数値の背後にあるプロファイリングデータを詳しく見ていきます。
📖 完全なソースを読む: HN AI Agents
👀 See Also

OpenClawとWhatsApp Cloud APIの統合
開発者がOpenClawをMetaの公式Cloud APIを使用してWhatsAppと直接通信するように設定し、そのセットアッププロセスを文書化して、他の人が散在するドキュメントを避けられるようにしました。

Claude Code向けのスキル作成原則(159のオープンソーススキルから)
開発者が、159のスキルを持つオープンソースのスキルレジストリを構築・維持する中で得た、Claude Code向けの効果的なスキル作成のための10の原則を公開しました。これらの原則は、実際のエージェントの使用状況から観察された実用的な実装パターンに焦点を当てています。

効果的な自動化のためのゲートウェイ切断の処理
ゲートウェイ切断時にAIコーディングエージェントの運用を維持するための実践的な解決策を探ります。Grafanaによる監視、自動再接続スクリプト、信頼性向上のための冗長パス活用などのヒントを含みます。

Claude Codeの27フックライフサイクル ビジュアルガイド
コミュニティによって作成されたリソースは、Claude Codeの全27種類のフックについて、視覚的かつ音声による解説を提供しています。各フックがいつ発火するか、その順序、受け取るデータを示しています。このプロジェクトはClaude Code自体を使用して完全に構築されました。