Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 980
Monis Iqbal Avatar asked Jul 23 '09 13:07

Monis Iqbal


2 Answers

This is covered in the Java Language Spec:

Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). String objects have a constant value. String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern.

You can also see for yourself using the javap tool.

For this code:

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

javap gives the following:

0:   getstatic     #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3:   ldc       #3; //String Efficiently stored String
5:   invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8:   getstatic     #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11:  ldc       #3; //String Efficiently stored String
13:  invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
like image 91
McDowell Avatar answered Sep 28 '22 05:09

McDowell


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
like image 25
matt b Avatar answered Sep 28 '22 07:09

matt b