<i id='lwpy1'><tr id='lwpy1'><dt id='lwpy1'><q id='lwpy1'><span id='lwpy1'><b id='lwpy1'><form id='lwpy1'><ins id='lwpy1'></ins><ul id='lwpy1'></ul><sub id='lwpy1'></sub></form><legend id='lwpy1'></legend><bdo id='lwpy1'><pre id='lwpy1'><center id='lwpy1'></center></pre></bdo></b><th id='lwpy1'></th></span></q></dt></tr></i><div id='lwpy1'><tfoot id='lwpy1'></tfoot><dl id='lwpy1'><fieldset id='lwpy1'></fieldset></dl></div>
    1. <legend id='lwpy1'><style id='lwpy1'><dir id='lwpy1'><q id='lwpy1'></q></dir></style></legend>
    2. <tfoot id='lwpy1'></tfoot>
      • <bdo id='lwpy1'></bdo><ul id='lwpy1'></ul>

      <small id='lwpy1'></small><noframes id='lwpy1'>

        StringBuilder vs. .concat vs. “+"eclipse中的操作员相对性能与命令行不同

        StringBuilder vs. .concat vs. quot;+quot; Operator relative performance different in eclipse than command line?(StringBuilder vs. .concat vs. “+eclipse中的操作员相对性能与命令行不同?)

      1. <tfoot id='kZ3dJ'></tfoot>
          <tbody id='kZ3dJ'></tbody>
        <i id='kZ3dJ'><tr id='kZ3dJ'><dt id='kZ3dJ'><q id='kZ3dJ'><span id='kZ3dJ'><b id='kZ3dJ'><form id='kZ3dJ'><ins id='kZ3dJ'></ins><ul id='kZ3dJ'></ul><sub id='kZ3dJ'></sub></form><legend id='kZ3dJ'></legend><bdo id='kZ3dJ'><pre id='kZ3dJ'><center id='kZ3dJ'></center></pre></bdo></b><th id='kZ3dJ'></th></span></q></dt></tr></i><div id='kZ3dJ'><tfoot id='kZ3dJ'></tfoot><dl id='kZ3dJ'><fieldset id='kZ3dJ'></fieldset></dl></div>

            <small id='kZ3dJ'></small><noframes id='kZ3dJ'>

            <legend id='kZ3dJ'><style id='kZ3dJ'><dir id='kZ3dJ'><q id='kZ3dJ'></q></dir></style></legend>
              <bdo id='kZ3dJ'></bdo><ul id='kZ3dJ'></ul>
                • 本文介绍了StringBuilder vs. .concat vs. “+"eclipse中的操作员相对性能与命令行不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在阅读有关 java 编译器如何在可能的情况下将与+"运算符连接的字符串编译为 StringBuilder 的实例,以及如何更好地使用简单的+"运算符,因为它们 编译成相同的代码.(除非您在 while 循环中构建字符串,在这种情况下显然最好使用 StringBuilder.)

                  I was reading about how when possible the java compiler will compile strings concatenated with the "+" operator into instances of StringBuilder, and how this makes it better to use the simple "+" operator since they compile to the same code. (Except when you are building the string in a while loop, in which case it is clearly best to use a StringBuilder.)

                  我还了解到,字符串上的 .concat 方法一直是最糟糕的选择(以至于它被 Findbugs 变成了一个错误!).

                  I've also read that the .concat method on strings is the worst choice all the time (so much so that it was made into a bug by Findbugs!).

                  所以我决定自己在eclipse中编写一个小的java类来测试它.我的结果让我有点吃惊.我发现,如果我在 Eclipse 和命令行中编译并运行它们,不同的方法相对更快或更慢.

                  So I decided to test it myself writing a little java class in eclipse. My results surprised me a bit. What I found was that different methods were relatively faster or slower if I complied and ran them in eclipse vs. on the command line.

                  首先我的日食结果是:

                  the total millis to concatenate with + was: 12154
                  the total millis to concatenate with .concat was: 8840
                  the total millis to concatenate with StringBuilder was: 11350
                  the total millis to concatenate with StringBuilder with a specified size was: 5611
                  

                  所以在eclipse中指定大小的StringBuilder最快,其次是.concat(奇怪),然后StringBuilder和+"连接几乎相同.

                  So in eclipse StringBuilder with the size specified was fastest, followed by .concat (weird), then StringBuilder and "+" concatenation were pretty much the same.

                  然而,我在命令行上的结果是:

                  My results on the command line, however, were:

                  the total millis to concatenate with + was: 4139
                  the total millis to concatenate with .concat was: 8590
                  the total millis to concatenate with StringBuilder was: 10888
                  the total millis to concatenate with StringBuilder with a specified size was: 6033
                  

                  所以当我从命令行编译并运行时,+"运算符显然是最快的,其次是带有大小的 String builder,然后是 concat,最后是普通 StringBuilder!

                  So when I compiled and ran from the commnad line the "+" operator was clearly the fastest, followed by String builder with size, then concat, and last was normal StringBuilder!

                  这对我来说没有意义.显然,我读到的所有 stackoverflow 答案都说 + 运算符编译成普通的旧 StringBuilder 实例必须是过时的.

                  This doesn't make sense to me. Obviously all the stackoverflow answers I read saying that + operators compile into normal old StringBuilder instances must be outdated.

                  有人知道这里到底发生了什么吗?

                  Does anyone know what's really going on here?

                  我正在使用 jdk1.7.0_07,据我所知,eclipse 和我的命令行都引用了完全相同的一个.我知道的唯一区别是 eclipse 是使用javaw",但从我读过的内容来看,这应该没什么区别.

                  I'm using jdk1.7.0_07, and so far as I can tell both eclipse and my command line are referencing the exact same one. The only difference I know of is eclipse is using "javaw", but from what I've read, that shouldn't make a difference.

                  如果你想验证我没有做错什么,这是我的测试课程,但我很确定它是可靠的.

                  Here's my test class if you want to verify I'm not doing anything wrong, but I'm pretty sure it's solid.

                  public class Test {
                  
                      static final int LOOPS = 100000000;
                      static final String FIRST_STRING = "This is such";
                      static final String SECOND_STRING = " an awesomely cool ";
                      static final String THIRD_STRING = "to write string.";
                  
                      /**
                       * @param args
                       */
                      public static void main(String[] args) {
                  
                          Test.plusOperator();
                          Test.dotConcat();
                          Test.stringBuilder();
                          Test.stringBuilderSizeSpecified();
                  
                      }
                  
                      public static void plusOperator() {
                          String localOne = FIRST_STRING;
                          String localTwo = SECOND_STRING;
                          String localThree = THIRD_STRING;
                  
                          Calendar startTime = Calendar.getInstance();
                          for (int x = 0; x < LOOPS; x++) {
                              String toPrint = localOne + localTwo + localThree;
                          }
                          Calendar endTime = Calendar.getInstance();
                          System.out.println("the total millis to concatenate with + was: " + 
                                  (endTime.getTimeInMillis() - startTime.getTimeInMillis()));
                      }
                  
                      public static void stringBuilder() {
                          String localOne = FIRST_STRING;
                          String localTwo = SECOND_STRING;
                          String localThree = THIRD_STRING;
                  
                          Calendar startTime = Calendar.getInstance();
                          for (int x = 0; x < LOOPS; x++) {
                              StringBuilder toBuild = new StringBuilder()
                                  .append(localOne)
                                  .append(localTwo)
                                  .append(localThree);
                          }
                          Calendar endTime = Calendar.getInstance();
                          System.out.println("the total millis to concatenate with StringBuilder was: " + 
                                  (endTime.getTimeInMillis() - startTime.getTimeInMillis()));
                      }
                  
                      public static void stringBuilderSizeSpecified() {
                          String localOne = FIRST_STRING;
                          String localTwo = SECOND_STRING;
                          String localThree = THIRD_STRING;
                  
                          Calendar startTime = Calendar.getInstance();
                          for (int x = 0; x < LOOPS; x++) {
                              StringBuilder toBuild = new StringBuilder(50)
                                  .append(localOne)
                                  .append(localTwo)
                                  .append(localThree);
                          }
                          Calendar endTime = Calendar.getInstance();
                          System.out.println("the total millis to concatenate with StringBuilder with a specified size was: " + 
                                  (endTime.getTimeInMillis() - startTime.getTimeInMillis()));
                      }
                  
                      public static void dotConcat() {
                          String localOne = FIRST_STRING;
                          String localTwo = SECOND_STRING;
                          String localThree = THIRD_STRING;
                  
                          Calendar startTime = Calendar.getInstance();
                          for (int x = 0; x < LOOPS; x++) {
                              String toPrint = localOne.concat(localTwo).concat(localThree);
                          }
                          Calendar endTime = Calendar.getInstance();
                          System.out.println("the total millis to concatenate with .concat was: " + 
                                  (endTime.getTimeInMillis() - startTime.getTimeInMillis()));
                      }
                  
                  }
                  

                  推荐答案

                  在 Oracle JDK 1.7 (javac 1.7.0_17) 上,+"运算符仍然使用 StringBuilder 实现,如运行所示javap -c 在类上获取字节码(这里只显示循环):

                  On Oracle JDK 1.7 (javac 1.7.0_17), the "+" operator is still implemented using StringBuilder, as shown by running javap -c on the class to get the bytecode (only showing the loops here):

                  public static void plusOperator();
                  Code:
                  
                    16: iload         4
                    18: ldc           #10                 // int 100000000
                    20: if_icmpge     53
                    23: new           #11                 // class java/lang/StringBuilder
                    26: dup           
                    27: invokespecial #12                 // Method java/lang/StringBuilder."<init>":()V
                    30: aload_0       
                    31: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    34: aload_1       
                    35: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    38: aload_2       
                    39: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    42: invokevirtual #14                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
                    45: astore        5
                    47: iinc          4, 1
                    50: goto          16
                  
                  
                  public static void stringBuilder();
                  Code:
                  
                    16: iload         4
                    18: ldc           #10                 // int 100000000
                    20: if_icmpge     50
                    23: new           #11                 // class java/lang/StringBuilder
                    26: dup           
                    27: invokespecial #12                 // Method java/lang/StringBuilder."<init>":()V
                    30: aload_0       
                    31: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    34: aload_1       
                    35: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    38: aload_2       
                    39: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
                    42: astore        5
                    44: iinc          4, 1
                    47: goto          16
                  

                  这两者之间唯一的区别是带+"的版本在循环中将StringBuilder转换为String.

                  The only difference between these two is that the version with "+" converts the StringBuilder to a String within the loop.

                  所以问题变成了:为什么您的测试会针对相同的代码显示如此不同的结果.或者更完整地说,为什么这不是一个有效的微基准测试.以下是一些可能的原因:

                  So the question becomes: why does your test show such different results for the same code. Or more completely, why is this not a valid micro-benchmark. Here are some possible reasons:

                  • 您正在计算挂钟时间.这意味着您实际上是在测量 JVM 在运行测试时所做的一切.其中包括垃圾收集(这很重要,因为您正在创建大量垃圾).您可以通过获取线程 CPU 时间来缓解这种情况.
                  • 您无法验证 HotSpot 何时或是否正在编译方法.这就是为什么您应该在任何微基准测试之前进行预热阶段:基本上,在运行实际测试之前多次运行 main().

                  这篇关于StringBuilder vs. .concat vs. “+"eclipse中的操作员相对性能与命令行不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Bytecode features not available in the Java language(Java 语言中不可用的字节码功能)
                  ClassCastException because of classloaders?(ClassCastException 因为类加载器?)
                  How can I add a Javaagent to a JVM without stopping the JVM?(如何在不停止 JVM 的情况下将 Javaagent 添加到 JVM?)
                  Cannot load 64-bit SWT libraries on 32-bit JVM ( replacing SWT file )(无法在 32 位 JVM 上加载 64 位 SWT 库(替换 SWT 文件))
                  Encourage the JVM to GC rather than grow the heap?(鼓励 JVM 进行 GC 而不是增加堆?)
                  Why a sawtooth shaped graph?(为什么是锯齿形图形?)
                    <tbody id='Rd21x'></tbody>

                      <bdo id='Rd21x'></bdo><ul id='Rd21x'></ul>

                    • <legend id='Rd21x'><style id='Rd21x'><dir id='Rd21x'><q id='Rd21x'></q></dir></style></legend>

                      • <tfoot id='Rd21x'></tfoot>

                          <small id='Rd21x'></small><noframes id='Rd21x'>

                            <i id='Rd21x'><tr id='Rd21x'><dt id='Rd21x'><q id='Rd21x'><span id='Rd21x'><b id='Rd21x'><form id='Rd21x'><ins id='Rd21x'></ins><ul id='Rd21x'></ul><sub id='Rd21x'></sub></form><legend id='Rd21x'></legend><bdo id='Rd21x'><pre id='Rd21x'><center id='Rd21x'></center></pre></bdo></b><th id='Rd21x'></th></span></q></dt></tr></i><div id='Rd21x'><tfoot id='Rd21x'></tfoot><dl id='Rd21x'><fieldset id='Rd21x'></fieldset></dl></div>