【问题标题】:What is the most efficient way to convert an int to a String?将 int 转换为 String 的最有效方法是什么?
【发布时间】:2009-03-17 12:23:11
【问题描述】:

说我有:

int someValue = 42;

现在我想将该 int 值转换为字符串。哪种方式效率更高?

// One
String stringValue = Integer.toString(someValue);

// Two
String stringValue = String.valueOf(someValue);

// Three
String stringValue = someValue + "";

我只是好奇是否有任何真正的区别或者一个比另一个更好?

【问题讨论】:

  • 正要问这个问题xd
  • 很高兴我已经为您解答了 :-)

标签: java string


【解决方案1】:

测试了 1000 万个数字 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

一个似乎赢了

编辑: JVM 是 Mac OS X 10.5 下的标准 '/usr/bin/java'

java版本“1.5.0_16” Java(TM) 2 运行时环境,标准版(内部版本 1.5.0_16-b06-284) Java HotSpot(TM) Client VM(build 1.5.0_16-133,混合模式,共享)

更多编辑:

按要求编码

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

【讨论】:

  • 经过一番热身后,1 和 2 的性能应该相同。大概吧。
  • 我更喜欢 String.valueOf(...) 因为它是返回 String 的 String 类中的静态方法,而不是返回 Integer 的 Integer 类中的静态方法。这看起来是更合适的做法。
  • 但是String.valueOf(s)的源代码是“return Integer.toString(s)”
  • 如果编译器仍然不知道如何优化 ""+int ,我会感到惊讶......如果不知道,最终他们应该认识到这一点并使其成为简单的字符串转换。到那时,它会是最快的,因为您节省了几次击键。
  • 通过预热,在最近的 JDK 上,我得到了非常非常不同的结果:基本上是平局。
【解决方案2】:

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

String.valueOf() 反过来调用Integer.toString()。因此,使用Integer.toString() 更好。

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

【讨论】:

  • String.valueOf(int) 不是 String.valueOf(Object)!
  • 那是 Integer 数据类型...它直接为 int 调用 Integer.toString()。
  • 问题是关于 int,而不是 Integer。
  • 哦,拜托,我一开始就忽略了这一点。我的错。并且 String.valueOf(int) 无论如何都会调用 Integer.toString() 。我试图说的本质是对 String 类的调用最终被路由到 Integer 类并被传达。这个答案的反对票看起来很难看!
【解决方案3】:

尽管根据measurements of cobbal,#1 似乎是最快的,但我强烈建议使用String.valueOf()。我这样做的原因是这个调用没有明确包含参数的类型,所以如果你以后决定将它从 int 更改为 double,则不需要修改这个调用。与 #2 相比,#1 的速度提升微乎其微,而且众所周知,“过早的优化是万恶之源”。

第三种解决方案是不可能的,因为它隐式创建了一个 StringBuilder 并将组件(在本例中为数字和空字符串)附加到其中,最后将其转换为字符串。

【讨论】:

  • 基准测试结果不同意 ""+i 如此缓慢。它似乎得到了优化,与替代品一样快。
【解决方案4】:

查看 JRE 的源代码,您可能会发现不同之处。或者没有。 实际上 Strinv.valueOf(int foo) 的实现如下:

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

和 Integer.toString(int foo, int radix)

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

这意味着如果你使用基数 10,你最好直接调用 Integer.toString(int foo)。对于其他情况,请使用 Integer.toString(int foo, int radix)。

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

【讨论】:

  • 但是如果经常走这条路,相信JVM也能乐观内联,让性能相当。
  • 不同的是另一个函数调用!
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    (大卫·哈纳克对面。)

    尽管根据 cobbal 的测量结果,#1 似乎是最快的,但我强烈推荐使用 Integer.toString()。我这样做的原因是这个调用明确地包含了参数的类型,所以如果你以后决定将它从 int 更改为 double,很明显这个调用已经改变了。如果它是二进制格式,您也会这样做,不是吗?与 #2 相比,#1 的速度提升微乎其微,而且众所周知,“过早的优化是万恶之源”。

    【讨论】:

    • 我,作为一名(高级编程语言的)程序员,在这一点上并不关心我的论点的类型;我只是想要它的字符串表示。 String.valueOf() 清楚地表达了这一点。恕我直言
    • 为了迂腐,String.valueOf 不一定返回相同的结果或对所有变量执行与 Integer.toString(int) 相同的操作。正是这些意料之外的语义差异驱使我直言不讳。
    • 如果意图或语义是“我想获取除整数以外的类型的对象,并获取它的字符串形式”,String.valueOf 更好地表达了这一点。如果意图或语义是“我必须取一个整数,并得到它的字符串形式”,那么 Integer.toString 会更好地表达。
    【解决方案7】:

    我对 JDK 11 的微基准测试结果与当前接受的答案有很大不同,显示 最小的运行时差异,并且没有内存使用/分配完全不同:

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

    我实际上wrote this microbenchmarka 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 2020-02-18
      相关资源
      最近更新 更多