简体   繁体   中英

At what point does defining a variable become more efficient than making method calls?

I was reading Google's tips on Android optimisation , and one of the first points they bring up is that you should avoid using short-term variables because it means more garbage collection. So, is there a point where you'd be better off defining a variable and using that instead of calling a accessor every time you want to use the object? Say, this:

for(int i = 0; i < 1000; i++) {
    foo.getBar() // then do something with it
}

As opposed to this:

Bar bar = foo.getBar();
for(int i = 0; i < 1000; i++) {
    bar // then do something with it
}

What's the difference, performance-wise?

From the link you provided: "you should avoid creating object instances you don't need to"

  1. object instances != short-term variables
  2. don't forget the second part of the sentence...

Local variables are usually allocated on the stack (where GC is irrelevant) while new object instances will be allocated on the heap - which is a totally different story. TMHO saying something like "don't do something if you don't really need to" has little value. Further, trying to avoid creating local variables when possible might have a really BAD effect on your code, read this

assuming no compiler optimizations

When you use

for(int i = 0; i < 1000; i++) {
    foo.getBar() // then do something with it
}

Your code will go to your instance referred by foo , execute its getBar() method, which will then return an instance/value of whatever it is supposed to return. This will be done for each and every one of your 1000 executions of that loop. After each execution is done, the value returned by getBar() will have to be garbage collected.

However, when you use:

Bar bar = foo.getBar();
for(int i = 0; i < 1000; i++) {
    bar // then do something with it
}

You get the value of foo.getBar() only once, outside your loop and store a copy of it locally. This local copy is then used in the loop 1000 times.

The second option is more efficient because your foo instance's getBar() method is called only once, instead of a thousand times. This means you don't execute the code in the getBar() method 1000 times, which is obviously worse than executing it once.

These are all really micro optimizations. Unless you are doing some real heavy lifting in getBar() , this won't have a noticeable effect. In a lot of cases, compiler optimizations will turn both of these into the exact same Bytecode, so you wouldn't worry about it anyways.

In this example, assuming bar is just an object returned by getBar and not created there is no difference as far as the GC is concerned.

However, method calls also have a small overhead and your second example will be more efficient.

However, if getBar creates a new object on each call, then 1000 new Bars will have created and then GCed in the second example whilst the first remains the same.

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