Search code examples
javastringoptimization

Does Java compiler handle inline Strings efficiently?


1.

static final String memFriendly = "Efficiently stored String";
System.out.println(memFriendly);

2.

System.out.println("Efficiently stored String");

Will Java compiler treat both (1 and 2) of these in the same manner?

FYI: By efficiently I am referring to runtime memory utilization as well as code execution time. e.g. can the 1st case take more time on stack loading the variable memFriendly?


Solution

  • public static void main(String[] args) {
        System.out.println("Hello world!");
    
        String hola = "Hola, mundo!";
        System.out.println(hola);
    }
    

    Here is what javap shows as the disassembly for this code:

    0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
    3:   ldc     #22; //String Hello world!
    5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
    8:   ldc     #30; //String Hola, mundo!
    10:  astore_1
    11:  getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
    14:  aload_1
    15:  invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
    18:  return
    

    Looks like the second string is being stored, whereas the first one is simply passed to the method directly.

    This was built with Eclipse's compiler, which may explain differences in my answer and McDowell's.

    Update: Here are the results if hola is declared as final (results in no aload_1, if I'm reading this right then it means this String is both stored and inlined, as you might expect):

    0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
    3:   ldc     #22; //String Hello world!
    5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
    8:   ldc     #30; //String Hola, mundo!
    10:  astore_1
    11:  getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
    14:  ldc     #30; //String Hola, mundo!
    16:  invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
    19:  return