2

When we split a long line of code into two for readability, it introduces a plus sign between the lines (if split between the text). For example splitting a long line in middle of text which is logging some text.

So, this should be avoided given additional string concatenation it brings into picture ? Or trade off of better readability weighs higher ?

Andy897
  • 6,915
  • 11
  • 51
  • 86

3 Answers3

2

All the usual Java compilers are way too mature to do something dumb like concatenate string literals at run time. Let's check. Given this code:

public class CatStrings {
  public static void main(String [] args) {
    String a = "This is a long long long string broken up "
        + "into parts to see if the compiler "
        + "optimizes the concatenation.";
    System.out.println(a);
  }
}

My Java 8 compiler - Oracle standard - does the right thing as shown by javap output:

  stack=2, locals=2, args_size=1
     0: ldc           #2                  // String This is a long long long string broken up into parts to see if the compiler optimizes the concatenation.
     2: astore_1
     3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
     6: aload_1
     7: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    10: return
Gene
  • 46,253
  • 4
  • 58
  • 96
1

Yes, there is a tiny bit of performance impact. The regular compiler doesn't do any optimization. It simply replaces the + operator with StringBuilder method calls. E.g. if you have String s = "x" + "y" + "z";, it may be replaced by String s = new StringBuilder().append("x").append("y").append("z"); before being compiled into bytecodes. But there is no real optimization here. It doesn't replace it by String s = "xyz"; before producing the byte code. I am not sure if the JIT compiler optimizes it before generating the native processor instructions. But even if it does, it is at run time causing a tiny performance hit.

Personally, I would care more for elegance and readability if they come at a cost of tiny performance hit.

VHS
  • 9,534
  • 3
  • 19
  • 43
1

It depends.

If the there are only constants, the javac takes care of it. The following program:

public class Main {
    public static void main(String[] args) {
        System.out.println("foo"+"bar");
    }
}

Turns into the following bytecode (removed some non relevant parts):

public class com/hazelcast/Main {

  // access flags 0x9
  public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 9 L0
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "foobar"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L1
    LINENUMBER 10 L1
    RETURN
   L2
    LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

You can see the foobar constant in there. So in this case there is no performance hit.

However if we would change the program to something more realistic:

public class Main {

    public static void main(String[] args) {
        int a = 1;
        System.out.println(a+"foo" + "bar");
    }
}

We get the following bytecode:

public class com/hazelcast/Main {

  // access flags 0x9
  public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 9 L0
    ICONST_1
    ISTORE 1
   L1
    LINENUMBER 10 L1
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ILOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
    LDC "foo"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    LDC "bar"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L2
    LINENUMBER 11 L2
    RETURN
   L3
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
    LOCALVARIABLE a I L1 L3 1
    MAXSTACK = 3
    MAXLOCALS = 2
}

As you can see, "foo" and "bar" are not automatically concatenated.

I have no idea if the JIT is able to remove the unwanted concatenation.

pveentjer
  • 10,545
  • 3
  • 23
  • 40