オプション1:
String newStr = someStr + 3 + "]";
オプション 2:
String newStr = someStr + "3" + "]";
パフォーマンス、メモリ、および一般的な慣行に関して、どのオプションが優れていますか? コードのメモリ使用量とそのパフォーマンスを測定するために使用できる推奨ツール/方法は何ですか (開始時間と終了時間を測定し、差を計算する以外に)
オプション1:
String newStr = someStr + 3 + "]";
オプション 2:
String newStr = someStr + "3" + "]";
パフォーマンス、メモリ、および一般的な慣行に関して、どのオプションが優れていますか? コードのメモリ使用量とそのパフォーマンスを測定するために使用できる推奨ツール/方法は何ですか (開始時間と終了時間を測定し、差を計算する以外に)
最初は次のようになります。
StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append (3);
sb.append ("]");
String newStr = sb.toString ();
2番目は次のようになります。
StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append ("3");
sb.append ("]");
String newStr = sb.toString ();
ここに分解があります:
public String foo (String someStr)
{
String newStr = someStr + 3 + "]";
return newStr;
}
public String bar (String someStr)
{
String newStr = someStr + "3" + "]";
return newStr;
}
public java.lang.String foo(java.lang.String);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: aload_1
5: invokestatic #18 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
8: invokespecial #24 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
11: iconst_3
12: invokevirtual #27 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
15: ldc #31 // String ]
17: invokevirtual #33 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #36 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: astore_2
24: aload_2
25: areturn
public java.lang.String bar(java.lang.String);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: aload_1
5: invokestatic #18 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
8: invokespecial #24 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
11: ldc #44 // String 3
13: invokevirtual #33 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: ldc #31 // String ]
18: invokevirtual #33 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #36 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_2
25: aload_2
26: areturn
両者の間に顕著な違いはありません。最も論理的で読みやすいと思われるものを使用してください。私は使うだろう
String newStr = someStr + "3]";
多くのメモリの問題を発見するのに役立つ優れた Java アプリケーション プロファイリング ツールとして、Jprofilerをお勧めします。
特にデスクトップアプリケーションの場合、オプション1と2のメモリ使用量に大きな違いはないと思います。
someString が定数であると仮定すると、どちらも定数式であり、コンパイル時に評価されます。これらは、同一のクラス ファイルと実行時の動作になります。
出典: Java 言語仕様は次のように書いています。
コンパイル時の定数式は、プリミティブ型の値を示す式、または突然完了しない String であり、以下のみを使用して構成されます。
プリミティブ型のリテラルと String 型のリテラル (§3.10.1、§3.10.2、§3.10.3、§3.10.4、§3.10.5)
加算演算子
+
and-
(§15.18)...
String 型のコンパイル時の定数式は、メソッド String.intern を使用して、一意のインスタンスを共有するために常に「インターン」されます。
someString が定数でない場合、最新のコンパイラのほとんどは StringBuilder を使用しますが、これはJava 言語仕様で明示的に許可されています。
文字列連結の結果は、2 つのオペランド文字列を連結した String オブジェクトへの参照になります。新しく作成された文字列では、左側のオペランドの文字が右側のオペランドの文字よりも前になります。
式がコンパイル時の定数式 (§15.28) でない限り、String オブジェクトは新しく作成されます (§12.5)。
実装では、変換と連結を 1 つのステップで実行して、中間の String オブジェクトを作成してから破棄することを回避できます。文字列連結の繰り返しのパフォーマンスを向上させるために、Java コンパイラは StringBuffer クラスまたは同様の手法を使用して、式の評価によって作成される中間 String オブジェクトの数を減らすことができます。
プリミティブ型の場合、実装では、プリミティブ型から文字列に直接変換することで、ラッパー オブジェクトの作成を最適化することもできます。