Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Agile forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

intermediate variable

 
nimo frey
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does this makes a difference in memory consumption/performance ?



Version 1:




Version 2:




In Version 1, I provide a intermediate variable computedValue and put this into the setter-method.
In Version 2, I do not provide a intermediate variable and put the computed value directly into the setter-method.

Which version is better in relation to memory consumption/performance? Or are there equal because of "call by reference".
 
Wouter Oet
Saloon Keeper
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is no performance difference and even if there was you should code for clarity and not for performance. Then after it's complete you can find the bottlenecks and optimize them. Because you can never accurately predict where the bottlenecks will be.
 
Rob Spoor
Sheriff
Pie
Posts: 20495
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a slight difference. The first piece of code requires 8 bytes on the stack for the variable. I believe it also requires an extra register store/load. However, unless resources are scarce, the first value is preferred because it allows you to a) debug better, and b) reuse the variable's value without refactoring. Especially if the computation uses a lot of time / memory it should be prevented to compute the same value twice in the same method, unless the results can be different.
 
nimo frey
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a slight difference. The first piece of code requires 8 bytes on the stack for the variable. I believe it also requires an extra register store/load


Thanks, this is exactly what I want to know.

I know, that version 1 is better for maintanance.


Then after it's complete you can find the bottlenecks and optimize them.


This is what I do.
 
nimo frey
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


when I use this:




should I set computedValue to null after setComputedValue, I do not need computedValue after copying the value to setComputedValue?

Is this better?:



Or will it copied by reference? Or will computedValue be garbaged collected?
 
Jan Hoppmann
Ranch Hand
Posts: 147
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Java calls by reference, so you'd probably get a null pointer exception.
 
Hauke Ingmar Schmidt
Rancher
Posts: 436
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The object on the heap will not be collected as long as a reference to it exists. The reference variable (computedValue) lives on the stack and will be destroyed when the declaring block is closed. You should use a block as small as possible, i.e. not declare the reference at the beginning of a method when you use it only within a for loop. But if you declare it within the for loop's block it will be created for every iteration... you even can create a new block only for the purpose of a tight variable scope.



a lives longer than needed.
b lives only in the enclosing block.
c lives only in the for loop but is created for every iteration.

Setting the reference null will allow the GC to collect the object. But it is a symptom of a block too large (e.g. a method that is too long and does different things).
 
nimo frey
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, thanks all, I guess, I got it:




The "Long computedValue" will be destroyed after excecution of method do(); Hence 8 bytes of the stack for the variable will be destroyed/released.

The first piece of code requires 8 bytes on the stack for the variable.



"MyObject" with its setValue of 100 will alive after method-excecution.


Please correct me, if I am wrong.
 
Hauke Ingmar Schmidt
Rancher
Posts: 436
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, the reference variable computedValue will be destroyed at the end of the block, in this case the method.

But with



you not only create the variable and assign it a value. You create a reference variable and, due to autoboxing, you create an object of type Long on the heap which will get a constructor parameter of "100". This object will live as long as a reference to it exists (e.g. as a field in "e").

If you would do



then no object would be created. The variable on the stack would not hold a reference but the value of 100. Most of the time this is preferable to using the boxing types (Long, Integer etc. instead of long, int...).
 
nimo frey
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thats really interesting.

So I should prefer the primitive types over the wrapper types.

Thanks for this advice!!

 
Wouter Oet
Saloon Keeper
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You should always prefer primitives over wrapper classes because wrapper classes are NullpointerExceptions waiting to happen. Only when it's not possible to use primitives then use wrapper classes (e.g. for storage in a Collection).
 
Ed Connery
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I also learned--from being nitpicked--to avoid autoboxing due to the extra (and unnecessary) conversions. Couple that with the possible NullpointerExceptions...

Perhaps my more significant mistake was that I was autoboxing and unboxing without realizing that I was doing so. I've heard that it's better to know what you're doing.
 
Hauke Ingmar Schmidt
Rancher
Posts: 436
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hm, sometimes "null" may be a valid value, primary example are database keys. Prefer a wrapper type there instead of using "special" values (like -1 for "not set" or 9999 for infinity) or introducing extra flags. In such cases a NPE would even be the preferred way over a piece of code that does something strange. I would not prefer primitive types automatically.

But I introduced the topic not for itself, but to demonstrate the live span of objects vs. variables.

 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic