new String() vs literal string performance

前端 未结 4 2077
名媛妹妹
名媛妹妹 2020-12-05 15:07

This question has been asked many times on StackOverflow but none of them were based on performance.

In Effective Java book it\'s given tha

相关标签:
4条回答
  • 2020-12-05 15:14

    The JVM maintains a pool of references to unique String objects that are literals. In your new String example you are wrapping the literals with an instance of each.

    See http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm

    0 讨论(0)
  • 2020-12-05 15:18

    as already have been answered the second retrieves the instance from the String pool (remember Strings are immutable).

    Additionally you should check the intern() method which enables you to put new String() into a pool in case you do not know the constant value of the string in runtime: e.g:

    String s = stringVar.intern();
    

    or

    new String(stringVar).intern();
    

    I will add additional fact, you should know that additionally to the String object more info exist in the pool (the hashcode): this enables fast hashMap search by String in the relevant data Strtuctures (instead of recreating the hashcode each time)

    0 讨论(0)
  • 2020-12-05 15:19

    The performance difference is in fact much greater: HotSpot has an easy time compiling the entire loop

    for (int j = 0; j < 1000; j++)
    {String s="hello World";}
    

    out of existence so the runtime is a solid 0. This, however, happens only after the JIT compiler kicks in; that's what warmup is for, a mandatory procedure when microbenchmarking anything on the JVM.

    This is the code I ran:

    public static void timeLiteral() {
      for (int j = 0; j < 1_000_000_000; j++)
      {String s="hello World";}
    }
    public static void main(String... args) {
      for (int i = 0; i < 10; i++) {
        final long start = System.nanoTime();
        timeLiteral();
        System.out.println((System.nanoTime() - start) / 1000);
      }
    }
    

    And this is a typical output:

    1412
    38
    25
    1
    1
    0
    0
    1
    0
    1
    

    You can observe the JIT taking effect very soon.

    Note that I don't iterate one thousand, but one billion times in the inner method.

    0 讨论(0)
  • 2020-12-05 15:29

    In the first case, a new object is being created in each iteration, in the second case, it's always the same object, being retrieved from the String constant pool.

    In Java, when you do:

    String bla = new String("xpto");
    

    You force the creation of a new String object, this takes up some time and memory.

    On the other hand, when you do:

    String muchMuchFaster = "xpto"; //String literal!
    

    The String will only be created the first time (a new object), and it'll be cached in the String constant pool, so every time you refer to it in it's literal form, you're getting the exact same object, which is amazingly fast.

    Now you may ask... what if two different points in the code retrieve the same literal and change it, aren't there problems bound to happen?!

    No, because Strings, in Java, as you may very well know, are immutable! So any operation that would mutate a String returns a new String, leaving any other references to the same literal happy on their way.

    This is one of the advantages of immutable data structures, but that's another issue altogether, and I would write a couple of pages on the subject.

    Edit

    Just a clarification, the constant pool isn't exclusive to String types, you can read more about it here, or if you google for Java constant pool.

    http://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf

    Also, a little test you can do to drive the point home:

    String a = new String("xpto");
    String b = new String("xpto");
    String c = "xpto";
    String d = "xpto";
    
    System.out.println(a == b);
    System.out.println(a == c);
    System.out.println(c == d);
    

    With all this, you can probably figure out the results of these Sysouts:

    false
    false
    true
    

    Since c and d are the same object, the == comparison holds true.

    0 讨论(0)
提交回复
热议问题