代码之家  ›  专栏  ›  技术社区  ›  Ascalonian

将int转换为字符串最有效的方法是什么?

  •  59
  • Ascalonian  · 技术社区  · 17 年前

    假设我有:

    int someValue = 42;
    

    // One
    String stringValue = Integer.toString(someValue);
    
    // Two
    String stringValue = String.valueOf(someValue);
    
    // Three
    String stringValue = someValue + "";
    

    我只是好奇有没有什么真正的区别,或者一个比另一个好?

    6 回复  |  直到 17 年前
        1
  •  78
  •   cobbal    17 年前

    测试了10万个数字作业

    One:
    real    0m5.610s
    user    0m5.098s
    sys     0m0.220s
    
    Two:
    real    0m6.216s
    user    0m5.700s
    sys     0m0.213s
    
    Three:
    real    0m12.986s
    user    0m11.767s
    sys     0m0.489s
    

    一个似乎赢了

    java version "1.5.0_16"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284)
    Java HotSpot(TM) Client VM (build 1.5.0_16-133, mixed mode, sharing)
    

    更多编辑:

    按要求编码

    public class One {
        public static void main(String[] args) {
            int someValue = 10;
            for (int i = 0; i < 10000000; i++) {
                String stringValue = Integer.toString(someValue);
            }
        }
    }
    

    案例2和案例3类似

    javac *.java; time java One; time java Two; time java Three
    
        2
  •  37
  •   Community Mohan Dere    8 年前

    即使根据 measurements of cobbal ,#1似乎是最快的,我强烈建议使用 String.valueOf() . 我这样做的原因是,这个调用不显式包含参数的类型,所以如果稍后决定将其从int更改为double,则无需修改这个调用。与#2相比#1的速度增益非常小,我们都知道,“过早优化是万恶之源”。

    StringBuilder 并将组件(在本例中为数字和空字符串)附加到该组件上,最后将其转换为字符串。

        3
  •  8
  •   Björn    17 年前

    前两个示例实际上是相同的,因为String.valueOf(int)使用Integer.toString(int)方法。第三种是丑陋的,而且可能效率较低,因为在Java中连接速度较慢。

        4
  •  8
  •   paweloque    17 年前

    看看JRE的源代码,您可能会看到其中的区别。或者没有。 事实上,Strinv.valueOf(int foo)的实现如下:

    public static String valueOf(int i) {
        return Integer.toString(i, 10);
    }
    

    和整数.toString(int foo,int基数)

    public static String toString(int i, int radix) {
       ...
       if (radix == 10) {
       return toString(i);
       }
       ...
    }
    

    concat解决方案首先将int值转换为字符串,然后与空字符串连接。这显然是最昂贵的案例。

        5
  •  5
  •   Tom Hawtin - tackline    17 年前

    尽管根据cobbal的测量结果,#1似乎是最快的,但我还是强烈建议使用Integer.toString()。我这样做的原因是,这个调用显式地包含了参数的类型,所以如果以后决定将它从int改为double,很明显这个调用已经改变了。如果是二进制格式,你也会这么做,不是吗?与#2相比#1的速度增益非常小,我们都知道,“过早优化是万恶之源”。

        6
  •  3
  •   Blasanka    8 年前

    "" + int 速度较慢,如上面David Hanak所示。

    String.valueOf() 内部通话 Integer.toString() . 因此,使用 Integer.toString()

    所以 Integer.toString() 是最快的。。

        7
  •  0
  •   tucuxi    4 年前

    我的 JDK 11的微基准测试结果非常不同 ,并且完全没有内存使用/分配差异:

     t (ms)   method
    
     12,30    "" + j
     12,57    Integer.toString(j)
     12.58    String.valueOf(j)
    

    我实际上 wrote this microbenchmark 搔痒 a different question ; 一位评论员建议我也在这里发表文章。要复制的代码(也来自该帖子)如下所示:

    package org.example;
    
    import com.google.caliper.BeforeExperiment;
    import com.google.caliper.Benchmark;
    import com.google.caliper.Param;
    import com.google.caliper.runner.CaliperMain;
    
    public class Main {
    
        @Param({"10", "100", "1000"})
        int size;
    
        private String[] output;
    
        @BeforeExperiment
        void setUp() {
            output = new String[size];
        }
    
        @Benchmark void quote(int reps) {
            for (int i = 0; i < reps; i++) {
                for (int j = 0; j < size; j++) {
                    output[j] = "" + j;
                }
            }
        }
    
        @Benchmark void toString(int reps) {
            for (int i = 0; i < reps; i++) {
                for (int j = 0; j < size; j++) {
                    output[j] = Integer.toString(j);
                }
            }
        }
    
        @Benchmark void valueOf(int reps) {
            for (int i = 0; i < reps; i++) {
                for (int j = 0; j < size; j++) {
                    output[j] = String.valueOf(j);
                }
            }
        }
    
        /*
        must have com.google.caliper:caliper:1.0-beta-3 in pom.xml; run with:
        mvn clean compile exec:java -Dexec.mainClass="com.google.caliper.runner.CaliperMain" -Dexec.args="org.example.Main"
         */
        public static void main(String[] args) {
            CaliperMain.main(Main.class, args);
        }
    }