0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Effective Java 9.63: 文字列結合のパフォーマンス

Posted at

9.63: 文字列結合のパフォーマンス

結論

文字列結合は 状況に応じて手段を選ぶ。
少量・単純な結合は + で可読性優先で良いが、ループ内や大量の連結、集合の結合では StringBuilder / String.join / Collectors.joining を使って中間オブジェクトの大量生成を避け、性能とメモリ効率を確保する。
ログではパラメータ化を使い、String.format は便利だがコストが高いことに注意する。


良い例

  • ループ外で StringBuilder を作る(ホットパスでの定番)
public String joinNames(List<String> names) {
    StringBuilder sb = new StringBuilder(names.size() * 16); // 初期容量を見積もる
    for (String name : names) {
        if (sb.length() > 0) sb.append(", ");
        sb.append(name);
    }
    return sb.toString();
}
  • コレクションを区切りで結合するなら標準 API を使う(簡潔で高速)
String csv = String.join(", ", names);
// または Stream API
String csv2 = names.stream().collect(Collectors.joining(", "));
  • ログはフォーマット済文字列を直接作らない(スレッドレベルが低い場合でも無駄な生成を避ける)
// SLF4J など
logger.debug("Processed {} records in {}ms", count, elapsed);

悪い例

  • ループ内で +=+)を使うと中間 String が毎回生成される(O(n^2) 的なコストになり得る)
public String badJoin(List<String> names) {
    String s = "";
    for (String name : names) {
        if (!s.isEmpty()) s += ", "; // 毎回新しい String を作る => 非常に遅い/メモリ浪費
        s += name;
    }
    return s;
}
  • String.format をホットパスで多用する(可読だが高コスト)。
for (Item it : items) {
    out.println(String.format("%s: %d", it.getName(), it.getCount())); // かなり重い
}

まとめ

  • 小さな、コードが読みやすい単発の結合は + を使って問題ない

  • ループで繰り返し結合する場合は 必ず StringBuilder を外で作る(初期容量を見積もると良い)

  • 複数要素を区切り付きで結合するなら String.join / Collectors.joining を使う

  • String.format は可読性が必要なケースで使うが、ホットパスや大量生成では避ける

  • スレッド安全を理由に同期された StringBuffer を選ぶ必要はほとんどない(必要なら別途同期設計を検討)

  • ログはパラメータ化(logger.debug("x={}", x))で不要な文字列生成を防ぐ

  • 性能が疑わしいときは 計測(プロファイラ/JMH) をしてから最適化する

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?