-1

According to https://www.geeksforgeeks.org/12-tips-to-optimize-java-code-performance/ at number 3, it says that during a for loop, you should define size beforehand and call that in the comparator. At first, that made sense to me assuming that the .size() method has to count up the elements every time it is called.

To verify this, I went to the source code for an ArrayList and went to the size method. What I found though was that it would just return an integer size that is stored as a value in the object. This is more of what I was expecting to find, but if this is the case, then why does the article say to avoid it? It does not explain why, it merely says to never do it. From what I saw, the list is already calling a variable that is stored in memory.

So, my question is: Is it actually going to help, or is it just something that the article got wrong?

ReBuff
  • 37
  • 6

2 Answers2

3

The answer is: "it depends".

  • It depends on what List class you are using.
  • It depends on how smart the JIT compiler is.
  • It depends on whether the size of the list changes during the loop execution.

For the most common List implementations, the current size is held in a field, and the size() method simply returns that field. In such cases, the code of the size() method will typically be inlined so that a size() call is a efficient as accessing the field directly. If the JIT compiler is able to deduce that the field doesn't change (and if there are no relevant Java Memory Model related constraints) then it could conceivably cache the size() result in a register.

But the flipside is that some List implementations may compute the size, and the JIT compiler may not be able to do some or all of those optimizations.

But the flipside of the flipside is that if size() is cheap, the overhead of calling it on each loop iteration may be too small to be significant.


Bottom line:

  • Beware of premature optimization.

  • Beware of articles that give overly simplistic / overly generalized advice.

  • Beware of articles that contain arrant nonsense like this:

    If possible, we can use primitive types instead of objects since data access from stack memory is faster than heap memory1.


1 - This appears in "5. Use Primitive Types Wherever Possible". Stack and heap memory use the same hardware and have the same access times. The real point he should be making in that context is that getting the value of an Integer involves an extra memory fetch, compared with accessing an int.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    It should be mentioned that when using the simpler `for(String s: objList) { execute code ..}` you are not even dependent on how `size()` has been implemented—the list’s `Iterator` implementation knows whether using size or some other mechanism for determining the end is better. When there’s no other use for `objList` than the manual iteration statement, the programmer can also write `for(String s: getData()) { execute code ..}` and omit the variable. This will still evaluate `getData()` only once. (All staying with the article’s example). – Holger Feb 08 '22 at 16:01
  • 2
    Speaking of the article’s nonsense, point 2 is bullshit as well, as the compiled form of `if(condition1 && condition2) { … }` and `if(condition1) { if(condition2) () { … }}` does not even differ. Introducing another `boolean` variable makes the compiled form even more complicated, without a benefit, but the article doesn’t even explain how the example’s `else` branch should work with the change. • Further, point 4 is nonsense, as the compiler knows how to use a `StringBuilder` and the article’s suggestion is *worse* than what the compiler generates. https://stackoverflow.com/a/54645780/2711488 – Holger Feb 08 '22 at 16:14
0

yes,it is actually going to help. i think call a method is coast more time than use a variable。

Digua
  • 54
  • 2
  • Sorry, but this is wrong ... in general. *Under some circumstances*, a Java method call will be inlined by the JIT compiler and the "cost" of accessing the variable via a method call will be identical to accessing the variable directly. The best we can say is that is *may* help. The flipside is that it *may* make no difference whatsoever. – Stephen C Feb 09 '22 at 00:01