简体   繁体   中英

Two questions about efficient work with loops

1. Suppose following situations.

First:

int x;
for (int i = 0; i < MAX; i++){
    // some magic with x
    System.out.println(x);
}

Second:

for (int i = 0; i < MAX; i++){
    int x;
    // some magic with x
    System.out.println(x);
}

So which piece of code is better and more efficient?

2. Another two situations.

First:

int size = array.length;
for (int i = 0; i < size; i++) {
    // do something with array[i]
}

Second:

for (int i = 0; i < array.length; i++) {
    // do something with array[i]
}

Is it more efficient to save array length to variable?

length is just a property in the array object, it doesn't take any time in getting the length.

It is the same as reading from a variable it doesn't need to loop over the whole array to get the length.

And the first two are just scopes.

Local - only available within the loop.

Global - available throught.


Assume you want remainders of numbers when divided by 2.

for(int i = 0; i < 10; ++i)
{
 int remainder = i % 2;
 System.out.println(remainder);
}

And assume calculating the sum of first 10 natural numbers.

int sum = 0;
for(int i = 0; i <= 10; ++i)
 {
    //declaring sum here doesnt make sense
     sum += i;
 } 
System.out.println(sum);//sum is available here.

PS: you could just the sum of n natural numbers formula.

1. What you should be more concerned with here, is not efficiency, but scope. Generally, you should strive to keep your variables as locally scoped as possible. This means, if you only need x within the loop, you should define it within the loop.

You get a number of benefits with keeping your variables as locally scoped as possible:

  • Your code will be much more readable to someone else
  • You won't accidentally assign to, or use the value of a variable you defined further up in your code that is still in scope, thus minimizing errors in your program
  • Most importantly, the garbage collector will free up any memory used by the variable as soon as it goes out of scope, keeping your program's performance high, and memory usage low.

You can read up more on variable scope and best practices from Josh Bloch's excellent book, " Effective Java " (scope is discussed in items 13 and 45). You might also want to read item 55, which discusses why it is important to optimize judiciously .

2. For the second part of your question, see The Skeet's answer here .

Here's an example:

public static void main(String[] args) {
    for(int i=0; i<getSize(); i++) {
        System.out.println("i: " + i);
    }
}

private static int getSize() {
    int size = new Random().nextInt(10);
    System.out.println("size: " + size);
    return size;
}

This outputs:

size: 2
i: 0
size: 4
i: 1
size: 4
i: 2
size: 8
i: 3
size: 0

Notice how getSize() is called for every iteration of the loop. In your example, calling .length won't make a huge difference, as the JIT runtime will know how to optimize this call. But imagine getSize() was a more complex operation, like counting the number of rows in a database table. Your code will be super slow as every iteration of the loop will call getSize() , resulting in a database roundtrip.

This is when you would be better off evaluating the value before hand. You can do this and still retain minimal scope for size , like this:

public static void main(String[] args) {
    for(int size = getSize(), i=0; i<size; i++) {
        System.out.println("i: " + i);
    }
}


private static int getSize() {
    int size = new Random().nextInt(10);
    System.out.println("size: " + size);
    return size;
}

size: 5
i: 0
i: 1
i: 2
i: 3
i: 4

Notice how getSize() is only called once, and also, the size variable is only available inside the loop and goes out of scope as soon as the loop completes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM