Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Cost of Calling array.length

While updating for loops to for-each loops in our application, I came across a lot of these "patterns":

for (int i = 0, n = a.length; i < n; i++) {     ... } 

instead of

for (int i = 0; i < a.length; i++) {     ... } 

I can see that you gain performance for collections because you don't need to call the size() method with each loop. But with arrays??

So the question arose: is array.length more expensive than a regular variable?

like image 639
Stroboskop Avatar asked Jul 30 '09 18:07

Stroboskop


People also ask

What is the value of array length?

By definition, the length property of an array is an unsigned, 32-bit integer that is always numerically greater than the highest index in the array. The value of the length is 232. It means that an array can hold up to 4294967296 (232) elements.

How do you call an array length in Java?

To get the size of a Java array, you use the length property. To get the size of an ArrayList, you use the size() method. Know the difference between the Java array length and the String's length() method.

Can you get the length of an array?

To find the length of an array, use array data member 'length'. 'length' gives the number of elements allocated, not the number inserted. Write a class with a main method that creates an array of 10 integers and totals them up. The elements of an array can be of any type, including a programmer-defined class.


2 Answers

No, a call to array.length is O(1) or constant time operation.

Since the .length is(acts like) a public final member of array, it is no slower to access than a local variable. (It is very different from a call to a method like size())

A modern JIT compiler is likely to optimize the call to .length right out anyway.

You can confirm this by either looking at the source code of the JIT compiler in OpenJDK, or by getting the JVM to dump out the JIT compiled native code and examining the code.

Note that there may be cases where the JIT compiler can't do this; e.g.

  1. if you are debugging the enclosing method, or
  2. if the loop body has enough local variables to force register spilling.
like image 57
jjnguy Avatar answered Sep 18 '22 14:09

jjnguy


I had a bit of time over lunch:

public static void main(String[] args) {     final int[] a = new int[250000000];     long t;      for (int j = 0; j < 10; j++) {         t = System.currentTimeMillis();         for (int i = 0, n = a.length; i < n; i++) { int x = a[i]; }         System.out.println("n = a.length: " + (System.currentTimeMillis() - t));          t = System.currentTimeMillis();         for (int i = 0; i < a.length; i++) { int x = a[i]; }         System.out.println("i < a.length: " + (System.currentTimeMillis() - t));     } } 

The results:

n = a.length: 672 i < a.length: 516 n = a.length: 640 i < a.length: 516 n = a.length: 656 i < a.length: 516 n = a.length: 656 i < a.length: 516 n = a.length: 640 i < a.length: 532 n = a.length: 640 i < a.length: 531 n = a.length: 641 i < a.length: 516 n = a.length: 656 i < a.length: 531 n = a.length: 656 i < a.length: 516 n = a.length: 656 i < a.length: 516 

Notes:

  1. If you reverse the tests, then n = a.length shows as being faster than i < a.length by about half, probably due to garbage collection(?).
  2. I couldn't make 250000000 much larger because I got OutOfMemoryError at 270000000.

The point is, and it is the one everyone else has been making, you have to run Java out of memory and you still don't see a significant difference in speed between the two alternatives. Spend your development time on things that actually matter.

like image 24
Grant Wagner Avatar answered Sep 20 '22 14:09

Grant Wagner