Jump to content
  • Advertisement
Sign in to follow this  
tom_mai78101

Java: Does making a variable within a while loop continuously make new instances of said variable?

This topic is 2665 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

For example:


int firstVariable = 0;
while (true)
{
int secondVariable = 1;
firstVariable++;
if (firstVariable > 0xFFFFFFF0)
break;
}


There are two variables, firstVariable and secondVariable. firstVariable is initialized to 0, and secondVariable is initialized to 1. After a long execution of this small code, what happens to secondVariable? Does Java create new instances of secondVariable every time it runs into that line of code, or it overrides the instance of secondVariable the moment it started existing in the memory?

Side question: Can it also happen in C and/or C++ in Visual Studios?

Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Second variable ceases to exist at the end of each loop as it goes out of scope and is reallocated on the next pass through.

That said the compiler *might* optimize this far you. C and c++ will behave the same. To prevent reallocation move the variable declaration outside the loop or make it static.

Share this post


Link to post
Share on other sites
My guess is if it's an int/base type and is a constant this should be stored in a register so actually there shouldn't be allocation. Being a VM register or a real one should make no difference. As for C++ my guess is modern compilers should issue a "variable is never used" warning. I suppose if the optimization is aggressive enough the variable might be ignored.

Share this post


Link to post
Share on other sites
Actually MSVC 2010 is much much better than I thought.

Your code turns out to be just:


xor eax, eax
ret


Regardlessy of the optimization level (if set).

Interestingly if I modify your code to return firstVariable I get this:


mov eax, 0xFFFFFFF1
ret


Even more interesting is what happens when I turn off optimizations. The while cycle is preserved and no internal register is used but the variable is preallocated.
This case is the same for debug and release builds (the latter with no otimization enabled).


int secondVariable = 1;
008E1016 mov dword ptr [secondVariable],1


No reallocation and thus no (huge) performance hit... I think this has been done specificly for helping debugging. In release you can put a breakpoint inside the while loop but the program stops on return 0;

So even if the compiler understands secondVariable isn't needed it tries to find a good mix between a reasonable debugging experience and real-world performance.

Thank you for submitting this. It's very interesting.

Share this post


Link to post
Share on other sites
Wow. I didn't know that Visual Studios allow looking at optimizations. How do you do that?

So, C and C++ are confirmed to not have a lot of performance hits with this problem. And probably Java is confirmed, although I don't think we are able to view the optimized Bytecodes, unlike Visual Studios 2010.

Share this post


Link to post
Share on other sites

Wow. I didn't know that Visual Studios allow looking at optimizations. How do you do that?

So, C and C++ are confirmed to not have a lot of performance hits with this problem. Would Java work differently? That's something I just wanted to know.





Woooooh there nelly, you are taking away a big mistake here!


In this case with this compiler on this operating system with this exact code the compilier efficiently optimized away your mistake. However, the language spec says that the second variable went out of scope and thus would be reallocated. Never EVER EVER rely on anything other than the langauge spec. This is the source of some many thousand bugs as to be scream worthy. There is nothing to say your code will run the same on Visual Studio 2015, or on GCC, or even after another service pack.



Don't kid yourself into thinking this is a language issue, its a compiler issue.

Share this post


Link to post
Share on other sites
The stack is weird. Variables declared inside a loop will only really get allocated the one time, but the stack pointer will move up and down making them valid/invalid. They will however get their constructors/destructors called every time the loop iterates. In the case of simple data like what you have, it doesn't make a huge difference. It should also be noted that the compiler MIGHT optimize it to be exactly the same as if it were outside the loop.

I tend to just declare the things inside the loop as it makes the scope more indicative of how I actually want it used, it's more in line with RAII and thus causes me to remove stupid error bugs, and it's very rarely a performance bottleneck.

It should also be noted that if you declare the variable outside the while loop without putting more braces in will give that variable more scope than you might intend it to have, which could bring its own problems.

edit: oh snap I missed that this was java not C++. My b. Not sure if the above applies to java. Let me go run and fact check and I'll update in a bit

edit 2: it looks like it is similar for java. The memory isn't reallocated each time, it is just reassigned. Both cases should end up having similar situations during assignment despite being inside or outside the loop.

this seems to indicate declaring inside is faster. If I'm understanding correctly it appears that because the variable is higher in the stack it has a greater chance of staying in the cache, which makes it faster.
http://stackoverflow.com/questions/407255/difference-between-declaring-variables-before-or-in-loop

Share this post


Link to post
Share on other sites

Wow. I didn't know that Visual Studios allow looking at optimizations. How do you do that?

So, C and C++ are confirmed to not have a lot of performance hits with this problem. Would Java work differently? That's something I just wanted to know.



You set a breakpoint and start debugging.
Then Debug->Windows->Disassembly

:)



Woooooh there nelly, you are taking away a big mistake here!


In this case with this compiler on this operating system with this exact code the compilier efficiently optimized away your mistake. However, the language spec says that the second variable went out of scope and thus would be reallocated. Never EVER EVER rely on anything other than the langauge spec. This is the source of some many thousand bugs as to be scream worthy. There is nothing to say your code will run the same on Visual Studio 2015, or on GCC, or even after another service pack.



Don't kid yourself into thinking this is a language issue, its a compiler issue.

I agree 100% with what you say. And also this is a basic type... a class is a totally different story.

My thought is this is a good measure of how that compiler works in this case. Surely there's a pattern and none should rely on that.
But to know the tools you use are so smart is interesting.

Share this post


Link to post
Share on other sites

The stack is weird. Variables declared inside a loop will only really get allocated the one time, but the stack pointer will move up and down making them valid/invalid. They will however get their constructors/destructors called every time the loop iterates. In the case of simple data like what you have, it doesn't make a huge difference.

If I understand what MSVC2010 does (which might NOT be the case) it looks that variable isn't in the stack.

When I see:

mov dword ptr [somevar],someconstantvalue

My understanding is it's implicitly pointing at the data segment, not the stack segment.

In pure asm style that should be

.data

somevar dd ?

.code

move dword ptr[somevar],someconstantvalue

Am I missing something? :unsure:

Share this post


Link to post
Share on other sites

If I understand what MSVC2010 does (which might NOT be the case) it looks that variable isn't in the stack.

When I see:

mov dword ptr [somevar],someconstantvalue

My understanding is it's implicitly pointing at the data segment, not the stack segment.


Why do you think that can't be on the stack? o.O

edit: all that's saying is that it's moving the value someconstantvalue of the size of a dword ptr into the location somevar iirc.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!