88776


`.append()`メソッドと`.concat()`メソッドの処理時間について質問です。  
以下のようなコードを作成し、`append`と`concat`の計測時間を`currentTimeMillis()`で計測した結果、`append`メソッドは
**1ミリ秒** 、`concat`メソッドは **0ミリ秒** という結果でした。

* * *

**currentTimeMillisを使ったコード：**

[code]

    public class Main{
      public static void main (String[] args){
        long start1 = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        sb.append("Hello ");
        sb.append("World");
        System.out.println(sb);
        long end1 = System.currentTimeMillis();
        System.out.println("currentTimeMillisでappend計測時間は" + ( end1 - start1 ) + "ミリ秒");
    
        long start2 = System.currentTimeMillis();
        String concatStr = "Hello ";
        concatStr =  concatStr.concat("World");
        System.out.println(concatStr);
        long end2 = System.currentTimeMillis();
        System.out.println("currentTimeMillisでconcat計測時間は" + ( end2 - start2 ) + "ミリ秒");
      }
    }
    
[/code]

非常に僅かな差だったので、もう少しどのくらい差があるのか確認しようと今度は`nanoTime()`で処理時間を計測しました。`nanoTime`で計測した結果、`append`は
**488069ナノ秒** ,`concat`は **68340ナノ秒** でした。

* * *

**nanoTimeを使ったコード：**

[code]

    public class Main{
      public static void main (String[] args){
        long start1 = System.nanoTime();
        StringBuilder sb = new StringBuilder();
        sb.append("Hello ");
        sb.append("World");
        System.out.println(sb);
        long end1 = System.nanoTime();
        System.out.println("nanoTimeでappend計測時間は" + ( end1 - start1 ) + "ナノ秒");
    
        long start2 = System.nanoTime();
        String concatStr = "Hello ";
        concatStr =  concatStr.concat("World");
        System.out.println(concatStr);
        long end2 = System.nanoTime();
        System.out.println("nanoTimeでconcat計測時間は" + ( end2 - start2 ) + "ナノ秒");
      }
    }
    
[/code]

* * *

私が作成したコードで計測した結果、どちらも`append`の処理時間のほうが`concat`より長いと言う結果でしたが、`append`メソッドは新しいオブジェクトを生成せずに連結するのに対し、`concat`は一度`new`をする（新しいオブジェクトを生成する）ので、CPUにより負荷がかかる`concat`メソッドのほうが処時間が長いと思っていたのですが、前述したように`append`の方が1ミリ秒、ナノ秒に関しては桁が違うほど差が出てしまいました。  
これは一体なぜでしょうか？私の`StringBuilder`の記述方法が、本来なら使わないCPUに負荷を掛ける書き方をしてしまったということでしょうか？  
また、もし私の`StringBuilder`もしくは`concat`メソッドの書き方が間違っていた場合、どのように書き直せばいいでしょうか？  
よろしくお願いいたします。

* * *

**追記：**  
もう一度図り直してみたところ、`nanoTime()`の`append`メソッドでは **816022ナノ秒** ,`concat`メソッドは
**34874ナノ秒** と言う結果でした。  
先程実行したときに比べて、計測時間が変わっています。そしてまた後にもう一度計測した結果、また違う時間が測定されました。  
違う結果が出力されてしまうほど不安定なコード（負荷をかけてしまう）を書いているということでしょうか？それとも、他になにか原因があるのでしょうか？  
ご教授いただけると嬉しいです。


CC BY-SA 4.0
2022-05-11T16:31:23.380
88768
2022-05-12T03:17:41.870
2022-05-11T18:00:17.167
51596
51596
question
java
appendメソッドとconcatメソッドによる計測時間の違い


多分、 **連結処理自体** は StringBuilder の方が速い（効率的）だと思います。理由は、

> appendメソッドは新しいオブジェクトを生成せずに連結するのに対し、concatは一度newをする（新しいオブジェクトを生成する）

の通り。では、なぜ、サンプルコードがその通りの結果にならなかったかというと、たった 2 つの文字列を連結するだけの処理では、String
オブジェクト（`String#concat` の場合）自体の初期化と、String + StringBuilder
オブジェクト（`StringBuilder#append` の場合）自体の初期化に要する時間がそのまま所要時間の差になってしまうからです。

次のように、連結処理を 10000 回ループさせてみれば、その差は歴然とします。

[code]

    public static void main(String[] args) {
        long start1 = System.nanoTime();
        String out1 = concat();
        long end1 = System.nanoTime();
        System.out.println(out1);
    
        long start2 = System.nanoTime();
        String out2 = append();
        long end2 = System.nanoTime();
        System.out.println(out2);
        
        System.out.println("");
        System.out.println("String#concat 計測時間は " + (end1 - start1) + " ナノ秒");
        System.out.println("StringBuilder 計測時間は " + (end2 - start2) + " ナノ秒");
    }
    
    private static String concat() {
        String out = "Hello, world!";
        for (int i = 0; i < 10000; i++) {
            out = out.concat(" Hello, world!");
        }
        return out;
    }
    
    private static String append() {
        StringBuilder sb = new StringBuilder("Hello, world!");
        for (int i = 0; i < 10000; i++) {
            sb.append(" Hello, world!");
        }
        return sb.toString();
    }
    
[/code]

ストレートにオブジェクトの新成回数がスピードの差を生んでいます。

[code]

    String#concat 計測時間は 242394739 ナノ秒
    StringBuilder 計測時間は 2665135 ナノ秒
    
[/code]


CC BY-SA 4.0
2022-05-12T03:17:41.870
88776
2022-05-12T03:17:41.870
7290
88768
answer