Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will the Java compiler optimize out String.length() in a for-loop's condition?

Tags:

java

Consider the following Java code fragment:

String buffer = "...";
for (int i = 0; i < buffer.length(); i++)
{
    System.out.println(buffer.charAt(i));
}

Since String is immutable and buffer is not reassigned within the loop, will the Java compiler be smart enough to optimize away the buffer.length() call in the for loop's condition? For example, would it emit byte code equivalent to the following, where buffer.length() is assigned to a variable, and that variable is used in the loop condition? I have read that some languages like C# do this type of optimization.

String buffer = "...";
int length = buffer.length();
for (int i = 0; i < length; i++)
{
    System.out.println(buffer.charAt(i));
}
like image 470
stackoverflowuser2010 Avatar asked Oct 17 '14 17:10

stackoverflowuser2010


2 Answers

The Java compiler (javac) performs no such optimization. The JIT compiler will likely inline the length() method, which at the very least would avoid the overhead of a method call.

Depending on which JDK you're running, the length() method itself likely returns a final length field, which is a cheap memory access, or the length of the string's internal char[] array. In the latter case, the array's length is constant, and the array reference is presumably final, so the JIT may be sophisticated enough to record the length once in a temporary as you suggest. However, that sort of thing is an implementation detail. Unless you control every machine that your code will run on, you shouldn't make too many any assumptions about which JVM it will run on, or which optimizations it will perform.

As to how you should write your code, calling length() directly in the loop condition is a common code pattern, and benefits from readability. I'd keep things simple and let the JIT optimizer do its job, unless you're in a critical code path that has demonstrated performance issues, and you have likewise demonstrated that such a micro-optimization is worthwhile.

like image 54
Mike Strobel Avatar answered Sep 27 '22 22:09

Mike Strobel


In Java (and in .Net), strings are length counted (number of UTF-16 code points), so finding the length is a simple operation.

The compiler (javac) may or may not perform hoisting, but the JVM JIT Compiler will almost certainly inline the call to .length(), making buffer.length() nothing more than a memory access.

like image 29
Mitch Avatar answered Sep 27 '22 20:09

Mitch