1

Java is an OOP language which has several in-built classes and methods for various purposes. One such example is the String class. The method length(), determines the length of the string. For example,

String str = "hello";
for(int i=0;i<str.length();i++)
{
//code
}

Here, the condition is evaluated if the variable i is less then the length of the string, then the loop iterates. But, does it determine the length every time?

Is the method length(), called every time before the condition is evaluated? If that is the case, then does Java store the variable's value internally in a register for quick access (or) the programmer must do it explicitly like this:

String str = "hello";
int len = str.length();
for(int i=0;i<len;i++)
{
//code
} 

How efficient is this approach?

Java Enthusiast
  • 1,161
  • 2
  • 15
  • 30
  • Just to complement the answer(s): Do the loop in the first way (`i < str.length()`). There are two places of possible optimizations: 1) The compiler could already optimize this code because a string is final and the length method refers to a final instance variable. 2) Modern JVM's use [just-in-time compilation](http://en.wikipedia.org/wiki/Just-in-time_compilation) (JIT). This can also possibly optimize the calls to `String.length()`. – Seelenvirtuose Mar 28 '15 at 07:28
  • @Seelenvirtuose He's not asking about optimizing the overhead from method calls. He's asking if calling `length` will calculate the size of the `String` every call, or will it simply return a number without any calculations after the first call. – Vince Mar 28 '15 at 07:30

2 Answers2

2

A modern JIT will probably notice that length() is a simple getter of a final class returning a final primitive value and replace the method call with the int value itself.The optimization penalty is true for C, amongst other languages, but not java. C's strlen walks the char array looking for the end-of-string character.

  • @VinceEmigh in C, you'd better store the result of strlen() to a variable instead of calling it at each iteration, whereas in Java, it's not necessary to store the result of string.length(). 1. because string.length() doesn't need to iterate through all the chars of the string as strlen() needs to do, 2. because the JIT optimizes the method call. – JB Nizet Mar 28 '15 at 07:14
  • 1
    @VinceEmigh no one... except the OP. That's precisely the question he's asking: does Java do it automatically, or does the developer has to do it explicitely: `int len = str.length();`. – JB Nizet Mar 28 '15 at 07:17
  • 1
    @VinceEmigh "My answer was no" ... as was Arslan's answer. What are you complaining about? – Seelenvirtuose Mar 28 '15 at 07:22
  • @Arslan, what would be the case, when the string changes dynamically, say I store the strings of varied length in a array and iterate through the same. In that case, there are going to be many method calls. right? – Java Enthusiast Mar 28 '15 at 07:33
  • @VinceEmigh Arslan's answer says: "length() is a simple getter of a final class returning a final primitive value". – JB Nizet Mar 28 '15 at 07:35
  • 1
    @VinceEmigh you're being paranoid. He said "The advice you've received". He did never say "the answer of Vince Emigh". Even if that's what he meant, it has been edited now, so get over it. This answer is maybe a bit too concise, but it's correct: it says the length() simply returns the value of a final field, unlike strlen which iterates through the chars, and it says that even if there is still a method call, this method call can be optimized by the JIT. Get over it. – JB Nizet Mar 28 '15 at 07:42
  • I mean by "Optimization penalty " is in C whenever you call strlen() method. it count all the chars until find null character. everytime counting number of characters in string is optimization penalty instead of just returning a field which is final without counting (getter). – Arslan Hashim Mar 28 '15 at 07:42
  • But no one is referring to C. In Java, String are immutable, meaning the size of the String cannot change. The OP didn't know, which is why he was asking "does Java optimize the calculation of size?" when the answer is really it depends on both the VM implementation (although most do, not all) and the method implementation. I'm not saying your answer is wrong in any way. I'm just saying that you've misunderstood what the OP was confused about, as well as the other 2 commenters. No harm meant at all, I was just curious as to how my advice was wrong; I don't wanna be giving out wrong advice – Vince Mar 28 '15 at 07:47
  • @JavaEnthusiast Yes in this case every string element in array of string is an object and compiler will call length() method on every object. – Arslan Hashim Mar 28 '15 at 07:48
  • @VinceEmigh I've received plenty of advices in my life. Most of them weren't made on StackOverflow. And none of them were made by Vince Emigh. It's also true for the OP. I don't see how the answer is targetting the wrong problem. It basically says the same thing as yours: 1. length() is simply a getter for a final field and does no iteration or computation, 2. the method call itself, which is already very fast, is optimized by the JIT. – JB Nizet Mar 28 '15 at 07:49
  • @JBNizet Not sure what your first statement relates to, but I think you're getting too heated over this. So it's sorta the same answer as mine? Have you met "sorta Greg"? Just because it's an answer doesn't mean it's a good one. Sure, saying "notice length is a getter" could be an answer, but the rest of the context is irrelevant to what the OP is asking about. If you wanna continue this argument, which I hope you don't, create a chat. I'm deleting my comments now – Vince Mar 28 '15 at 07:51
  • 1
    Of course no one referring to C but I am. I made an example to explain. Because optimization is comparative term, near to me. – Arslan Hashim Mar 28 '15 at 07:53
  • @ArslanHashim That's fine, but I personally I think that may confuse the OP. As @JBNizet pointed out, your question *does* somewhat answer his questioning by mentioning `length()` is a getter method, but no one is asking about the act of inlining a method call. That's what I was trying to tell JB, but he chose "the other path" and got all god-complex on me. I was only trying to prevent confusion, not say whos right or wrong based on technical facts. – Vince Mar 28 '15 at 08:18
0

String#length simply refers to a variable. Nothing else. The structure is like this:

class String {
    private int length;

    public int length() {
        return length;
    }
}

Strings are immutable, so theres no reason for it to change in the first place; the only time the length needs to be calculated is when the String is created.

It's common practice to perform the calculations when needed, update a size variable, then refer to a getter for that when you need to get the size. That way you aren't wasting time calculating the size when it hasn't changed. You can see this in ArrayList

As for "under the hood" optimizations, it depends on the VM implementation, as well as the code being executed. Inlining could be performed, as well as some run-time optimizations. But in the end, it depends on the code and the VM.

Vince
  • 14,470
  • 7
  • 39
  • 84
  • String#length() is an instance method of class string @Vince. How can it be a variable? can you explain it in detail with more examples – Java Enthusiast Mar 28 '15 at 07:08
  • @JavaEnthusiast Check out my edit. Rather than the method calculating the size, the size is calculated only when needed (in this case, when the `String` is created). `length()` simply refers to a variable which contains the size. `length()` is considered a [getter method (or accessor method)](http://stackoverflow.com/questions/2036970/how-do-getters-and-setters-work) – Vince Mar 28 '15 at 07:11
  • what would be the case, when the string changes dynamically, say I store the strings of varied length in a array and iterate through the same. In that case, there are going to be many method calls. right? – Java Enthusiast Mar 28 '15 at 07:34
  • @JavaEnthusiast String are immutable, so they wont change. Any attempts at changing a String results in a new String object containing the modifications. Even `String#toCharArray()` returns a new object, to make sure you can't modify a pre-existing String. The size of the String is calculated when it's created, and stays the same through-out the life-cycle of that String object – Vince Mar 28 '15 at 07:39
  • Thanks. Now I have a clear idea about it :). Thank you so much – Java Enthusiast Mar 28 '15 at 07:44
  • @JavaEnthusiast No problem :) Don't forget to mark as accepted answer if it has answered your question! (sorry for asking twice, but a lot of people forget or don't care to) – Vince Mar 28 '15 at 07:44
  • Both the answers are really good. I don't know which one to upvote – Java Enthusiast Mar 28 '15 at 07:56
  • @JavaEnthusiast Feel free to accept the other answer. I don't mind; he has 11 rep, he's technically right, so I wouldn't mind at all. But I assumed my answer was the one that helped you with your problem, and the point of accepting answers is to let others know "this answer helped me". If the other answer helped you in the same way (or more), then feel free to accept it. Don't worry about people taking it personally; they shouldn't. Just don't let peer pressure alter your decision – Vince Mar 28 '15 at 08:23