javastringoptimizationstring.format

Will a good Java compiler omit a call to `String.format` with no format specifiers?


For example, if you have a line of code like this:

String vacuouslyFormatted = String.format("Number of items: 100");

Will the call to String.format most likely be omitted by the compiler since it does not affect the object referenced by vacuouslyFormatted in any way?


Solution

  • No; java isn't that kind of ecosystem.

    All optimization is done by the runtime. The compiler (which turns .java files into .class files) must follow the spec precisely, and the spec (unlike, say, C), gives pretty much zero leeway or flexibility to the compiler. This source file must be turned into that sack of bytes. To the byte. Precisely. Or it's not a java compiler.

    If you write String.format in the code, that has to be in the class file. After all, what if in some future edition of the String class that you end up running that code with, the String.format("justAString") call would produce something else? javac shouldn't make a decision that the spec of String.format cannot change like this.

    What will happen in JDK21 (or 22, I'm not quite sure which version will get it), is compiler-supported string format directives. It looks like passing a string as it's a method:

    String name = "Jane";
    int age = 8;
    String formatted = STR."My name is \{name}, and I am \{age} years old";
    assert "My name is Jane, and I am 8 years old".equals(formatted);
    

    A runtime advantage here is that the compiler lops that format template string up into 3 substrings and 2 substitutions ("My name is", ", and I am ", and " years old") and passes all that to STR (which you'd have to import). This means STR no longer has to, at runtime, go through the string and find %.

    In contrast to String.format("My name is %s, and I am %d years old", name, age); where the code of format has to loop through the string and find percentage symbols.

    Even in your case (String.format("A string with no percent symbols and no arguments")) it still has to look through for percentages. With the string templating feature it wouldn't have to do that.

    The key point is that The java language spec would spell out that this is an option (in fact, it would spell out that a compiler must do it this way, if it deviates it would be just as wrong as a JDK20 compiler that compiles String.format("abc") as just "abc").

    NB: Standard 'future java' disclaimer: The OpenJDK team's discussions and feature implementations leave syntax to the very last moment, and are not at all interested in syntax discussions. It's not about what it looks like, it's about what it does. So if you like the idea but you find STR."Hello" looks weird, then [A] you may need to understand the full context of it all: Java doesn't break backwards compatibility; loads of proposals on how things should look are not possible because it's already valid java and therefore the meaning of it cannot just be changed without an extremely good reason to do so, and [B] that's not the interesting part, they probably don't currently care about syntax too much). I included what it currently looks like just as an aid to show what it does.