LoginSignup
5
5

More than 5 years have passed since last update.

文字列「00010」を「10」にする方法の速さ比較

Last updated at Posted at 2016-09-02

文字列「00010」を「10」に変換する方法をいくつか考え、速さを比較しました。

前提条件は以下です。

  • 空文字の入力は想定しない。
  • 先頭の0を除く文字列はint型に収まる数値。
  • 以下のように先頭から余計な0を除く。
    • 00010 -> 10
    • 10010 -> 10010
    • 00 -> 0
    • 0 -> 0
    • 1 -> 1

以下の方法を比較しました。

  • Integer#parseInt()メソッドを使用
  • BigDecimalを使用
  • String#replaceAll()メソッドを使用

実行環境は以下の通りです。

  • DELL VOSTRO 1540
  • Windows 10 Pro 32bit
  • Intel Celelron 2.00 GHZ
  • メモリ 2.0GB
  • HDは約300GB

比較に使ったソースは以下です。

Java
public class HelloPrefixTrim {

    private static final String REG1 = "^0+";
    private static final String REP1 = "";

    private static final String REG2 = "^0+$";
    private static final String REP2 = "0";

    private static final String s1 = "00010";
    private static final String s2 = "10010";
    private static final String s3 = "00";
    private static final String s4 = "0";
    private static final String s5 = "1";

    private static int COUNT = 200000;

    public static void main(String[] args) {

        long start, end;

        start = System.currentTimeMillis();
        test1();
        end   = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        test2();
        end   = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        test3();
        end   = System.currentTimeMillis();
        System.out.println(end - start);

    }

    private static void test1() {

        for (int i = 0; i < COUNT; i++) {
            String.valueOf(Integer.parseInt(s1));
            String.valueOf(Integer.parseInt(s2));
            String.valueOf(Integer.parseInt(s3));
            String.valueOf(Integer.parseInt(s4));
            String.valueOf(Integer.parseInt(s5));
        }

    }

    private static void test2() {

        for (int i = 0; i < COUNT; i++) {
            new BigDecimal(s1).toString();
            new BigDecimal(s2).toString();
            new BigDecimal(s3).toString();
            new BigDecimal(s4).toString();
            new BigDecimal(s5).toString();
        }

    }

    private static void test3() {

        for (int i = 0; i < COUNT; i++) {
            replaceAll(s1);
            replaceAll(s2);
            replaceAll(s3);
            replaceAll(s4);
            replaceAll(s5);
        }

    }

    private static String replaceAll(String s) {
        if (s.matches(REG2)) {
            return REP2;
        } else {
            return s.replaceAll(REG1, REP1);
        }

    }
}
結果
119
164
1098

Integer#parseInt()メソッドが一番速いという結果になりました。

@shiracamus さんによる処理との比較

コメントにて、@shiracamus さんに独自の処理を教えていただきました。以下、追加して結果を載せました。

HelloPrefixTrim2
public class HelloPrefixTrim2 {

    private static final String REG1 = "^0+";
    private static final String REP1 = "";

    private static final String REG2 = "^0+$";
    private static final String REP2 = "0";

    private static final String s1 = "00010";
    private static final String s2 = "10010";
    private static final String s3 = "00";
    private static final String s4 = "0";
    private static final String s5 = "1";

    private static int COUNT = 200000;

    public static void main(String[] args) {

        long start, end;

        start = System.currentTimeMillis();
        test1();
        end   = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        test2();
        end   = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        test3();
        end   = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        test4();
        end   = System.currentTimeMillis();
        System.out.println(end - start);
    }

    private static void test1() {

        for (int i = 0; i < COUNT; i++) {
            String.valueOf(Integer.parseInt(s1));
            String.valueOf(Integer.parseInt(s2));
            String.valueOf(Integer.parseInt(s3));
            String.valueOf(Integer.parseInt(s4));
            String.valueOf(Integer.parseInt(s5));
        }

    }

    private static void test2() {

        for (int i = 0; i < COUNT; i++) {
            new BigDecimal(s1).toString();
            new BigDecimal(s2).toString();
            new BigDecimal(s3).toString();
            new BigDecimal(s4).toString();
            new BigDecimal(s5).toString();
        }

    }

    private static void test3() {

        for (int i = 0; i < COUNT; i++) {
            replaceAll(s1);
            replaceAll(s2);
            replaceAll(s3);
            replaceAll(s4);
            replaceAll(s5);
        }

    }

    private static String replaceAll(String s) {
        if (s.matches(REG2)) {
            return REP2;
        } else {
            return s.replaceAll(REG1, REP1);
        }

    }

    private static void test4() {

        for (int i = 0; i < COUNT; i++) {
            trimzero(s1);
            trimzero(s2);
            trimzero(s3);
            trimzero(s4);
            trimzero(s5);
        }

    }

    private static String trimzero(String s) {
        int i = 0, last = s.length() - 1;
        while (i < last && s.charAt(i) == '0') i++;
        return s.substring(i);
    }
}
121
192
1121
30

@shiracamus さんの方法が圧倒的に速いです。

修正履歴

20160902

  • 入力が空文字や0の場合を考慮し、全体的に修正。
  • @shiracamus さんに教えていただいたプログラムを追加。
5
5
6

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
5
5