LoginSignup
0
1

More than 5 years have passed since last update.

String、StringBuilder、StringBufferのスピード比較テスト

Posted at

・Stringクラスを使用して文字列の連結処理を行うと、毎回Stringオブジェクトが生成される。

・これはオーバーヘッドとなるので、StringBuilderやStringBufferクラスを使用すべきと言われている。

・私は「そのくらいのオーバーヘッドはたいしたことないだろ」とこれらのクラスは使用していない。もちろん回数が多い場合は使用すべきであるが、(私には)そのような状況はあまりない。

・これらのクラスを使用すると、ソースコードが見にくくなるのがちょっと問題。

・どのくらい違うのか計測してみた。

・大雑把に言って、Stringを直接操作した場合は10倍以上かかっている。
・しかしそもそも絶対時間は大きくはないので、回数が少ない場合は、String直接操作でよいと考える。

・StringBuffer(StringBuilder)を使用する場合の判断に使っていただきたい。

・なお百万回になると、StringBufferの方がStringBuilderよりも速くなっている。理由は(私には)不明。

・ここでは一回の結果を示すが、何度やっても傾向は同じである。

・StringBufferとStringBuilderの違い。前者はスレッドセーフで、後者はスレッドセーフではない。後者が新しい。

・なぜスレッドセーフにしなかったかと言えば、スレッドで使う場合は非常に少なく、それがためにスピードを落としたくないということ(と想像する)。

・StringBuilderをスレッドで使いたい場合は、自分で制御するようにしなさいということ。

Tips0016.java
package jp.avaj.lib.algo;

import java.util.Date;

import jp.avaj.lib.test.L;

class Tips0016 {
  private static int CNT0;
  private static final int CNT1 = 100; //
  public static void main(String[] args) {
    L.p("==== 一万回");
    CNT0 = 10000;
    execString();
    execStringBuilder();
    execStringBuffer();

    L.p("==== 十万回");
    CNT0 = 100000;
    execString();
    execStringBuilder();
    execStringBuffer();

    L.p("==== 百万回");
    CNT0 = 1000000;
    execString();
    execStringBuilder();
    execStringBuffer();

  }

  private static void execString() {
    long start = (new Date()).getTime();
    for (int i=0; i<CNT0; i++) {
      String s = "";
      for (int j=0; j<CNT1; j++) {
        s += "aaa";
      }
    }
    long end = (new Date()).getTime();
    diff("String",start,end);
  }
  private static void execStringBuilder() {
    long start = (new Date()).getTime();
    for (int i=0; i<CNT0; i++) {
      StringBuilder sb = new StringBuilder();
      for (int j=0; j<CNT1; j++) {
        sb.append("aaa");
      }
    }
    long end = (new Date()).getTime();
    diff("StringBuilder",start,end);
  }
  private static void execStringBuffer() {
    long start = (new Date()).getTime();
    for (int i=0; i<CNT0; i++) {
      StringBuffer sb = new StringBuffer();
      for (int j=0; j<CNT1; j++) {
        sb.append("aaa");
      }
    }
    long end = (new Date()).getTime();
    diff("StringBuffer",start,end);
  }

  private static void diff(String desc,long start,long end) {
    L.p(desc+"="+(end-start));
  }
}

実行結果は次のとおり。

Tips0016.txt
==== 一万回
String=230
StringBuilder=31
StringBuffer=52
==== 十万回
String=1383
StringBuilder=149
StringBuffer=352
==== 百万回
String=12336
StringBuilder=1433
StringBuffer=1388

0
1
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
1