Raised This Month: $51 Target: $400
 12% 

[FAQ] Whether to create variables inside/outside loops


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
ezio_auditore
Senior Member
Join Date: May 2013
Old 11-03-2014 , 15:33   [FAQ] Whether to create variables inside/outside loops
Reply With Quote #1

So, it had been a long time and as the most (experienced) coders say that one should not create variables inside loops. I recently submitted a plugin and was told to not create variables inside the loops. So, I did a bit of research and with my findings, I decided to write this tutorial (or not a tutorial at all).

Q1.) Why should one create variables outside the loops
A.) In 99% of cases, it is found that the variables are to be used after the loop. So, in that cases, it is a convention to declare variables outside the loops. But consider of a situation where you need to end the scope of a variables at the moment when the loop returns, you would conventionally declare variables inside the loop to limit their scope.

Consider this example
Code:
public plugin_init(){     register_plugin("Tutorial_Var_Inside_Outside", "0.1", "ezio_auditore")     register_clcmd("say count", "count_100") } public count_100(id) {     //Variable sum declared outside the loop     new sum = 0     for (new i = 1 ; i <= 100 ; i++) {         //Here we want to display the value of i when divided by 2 and then add it to the total         //The value of j is limited to this scope only because we want it to be used here only         new j = i / 2;         sum += j         client_print(id, print_chat, "%i", j)     }     //It is clear that why sum is declared before the loop     client_print(id, print_chat, "The sum is %i", sum) }

In this simple (very simple indeed) plugin, it is clear that we want to use the value of sum outside the loop so it is declared before the loop. On the other hand, we want j's scope to be limited inside the loop, it is declared there. Now it is clear that the declaration of variables inside/outside the loop is a mere convention. But there are many things that matters, we will go into depth in a short time.

Q2.) Effects on memory
A.) There are many "pros and cons" of declaring the variables outside and inside the loops. In both of the cases, there is a similarity. Lets take the above discussed loop once again.
Code:
public count_100(id) {     //Variable sum declared outside the loop     new sum = 0     for (new i = 1 ; i <= 100 ; i++) {         //Here we want to display the value of i when divided by 2 and then add it to the total         //The value of j is limited to this scope only because we want it to be used here only         new j = i / 2;         sum += j         client_print(id, print_chat, "%i", j)     }     //It is clear that why sum is declared before the loop     client_print(id, print_chat, "The sum is %i", sum) }
So, what basically happens with sum and j that their references are "un-linked and linked again and again". I will elaborate it.
At first, the value of sum is 0, i.e., sum takes 4 bytes in memory and the variable refers to the 0 stored in memory. At first iteration, sum's value is changed. Now this variable doesn't refer to the 0 anymore, but its reference is now linked with its new value. At second iteration, sum's value changes again, but its reference to the value of first iteration gets cleared and it refers to the new value which again takes 4 bytes, but the 0 and the value of the first iteration is still in the memory. So, what we have now. Variable sum is still taking 4 bytes in memory but its reference to the previous values gets cleared and is associated with the new ones. Or in other words, sum is taking only 4 bytes, but it renders the eight bytes of memory unusable since they already have some value in them. The same happens with j but this contains several more overheads.

Q3.) If both are same, then what's the difference?
A.) If this is the question which came into your mind while reading the second answer. They are different in many aspects. First and the most major difference between them is that their memory footprint is different. Moreover, the variables created inside the loop would immediately throw-away and declaring inside-the-loop involves certain overheads. According to my findings, language makes a great difference. It depends on the language and the exact use. For instance, in C# 1 it made no difference. In C# 2, if the local variable is captured by an anonymous method (or lambda expression in C# 3) it can make a very significant difference. I tested the same type of code in Java, and the average execution time was less in inside-the-loop case!

Conclusion
After all this, I would conclude that there is no major difference (but the difference is there) in both the cases. It is the choice of a person whether he wants to create the variables inside or outside the loops, but one should prefer them to be declared outside.

NOTE: If am wrong anywhere, I would like to be corrected
__________________
ezio_auditore is offline
Send a message via Skype™ to ezio_auditore
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 11-04-2014 , 06:02   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #2

I don't have much experience in memory management from language perspective to make tutorial nor to elaborate, but I can tell at least this:

Q1. Defining a scope for used variables is welcome. In your example you can do that easily:
  • either by declaring the new variable inside the for like
    Code:
    for (new i, j; i < 100; ++i) { }
  • or by creating a new scope
    Code:
    {     new j;     for (new i; i < 100; ++i)     {     } }
    It's usually a good idea to declare variables near where you use them.

Q2. I'm not sure to understand your 'link/unlik" or "reference of value". This seems like an hazardous explanation to state the obvious that the point is not about used memory, something you started to explain in Q3, but how is expensive to manage memory in this context.

Q3. Pawn is not C/++/#/Java/whatever. It's well known Pawn compiler is not smart. That's it, if you declare a variable in a loop, this one will be allocated/freed at each loop. This is generally an expensive operation, a certain overhead as you said. This can be confirmed by disassembling an .amxx file. With others languages, this will be most likely allocated one time. Of course, one cell and few loops is trivial, it depends context, but still unnecessary operations you could easily avoid.


Your conclusion is kind of hazardous as well. There is a difference and in Pawn, even if not a big deal in most of cases, it would be a good practice to avoid to declare variables in a loop. You should not expect much from the compiler, that's why we need to care about practices like doing stuff in designed scope, caching native/array value, and such.
__________________
Arkshine is offline
ezio_auditore
Senior Member
Join Date: May 2013
Old 11-04-2014 , 06:10   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #3

Well it is a fact that I can't explain things very well.

About Q2.) By link/unlink I mean that whether the variables holds the reference to the variables previously different.

Q3.) These were the things I was told when I asked my teacher about the difference between declaring the variables outside/inside. (A Little Help From StackOverflow)

Conclusion.
Well thats my opinion. I am sorry if I am wrong. But I support the practice of declaring them outside.
__________________
ezio_auditore is offline
Send a message via Skype™ to ezio_auditore
GuskiS
Veteran Member
Join Date: Aug 2007
Location: Latvia
Old 11-04-2014 , 09:36   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #4

What about declaring an array in loop? For example:
PHP Code:
new array[1000];
for(...)
{
  array[
0] = 0;
  array[
1] = 1;
  array[
2] = 2;
}

or

for(...)
{
new array[
1000];
  array[
0] = 0;
  array[
1] = 1;
  array[
2] = 2;

As you can see, I only use 3 elements from that 1000, so what happens when I declare it in loop? You are saying that creating variable takes 4 bytes and asigning it with new value also take 4 bytes, but if I leave other untouched?
__________________
Finished mods:
Trouble in Terrorist Town
MurderMod
The Hidden
Cowboys vs Indians
JailBreak Supreme
Survival Madness

Last edited by GuskiS; 11-04-2014 at 09:36.
GuskiS is offline
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 11-04-2014 , 10:10   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #5

This is not something that should be dabated too much. Do you think that having the same var created x times is better than having it created one time ? In a loop it will be created and destroyed every time, but when you declare it outside the loop this will happen just one time. No matter if the loop will iterate just two times, it's still more work to do comparing with a var declared outside. I'm not saying that it will kill the server memory or so, but we need to keep good practices, and only for the sake of having good examples in every code we should not declare a variable inside a loop. A plugin should be a good example of "how to do that thing", and it should use the best ways of reaching the target, because, when others will look in your code they must be able to learn from it and to find a good example.

Look here:
Code:
new var loop { //do sth with the var } //end of public //the variable "var" will be destroyed here

And here:
Code:
loop { new var//var will be intialized here //do stuff //var will be destroyed here }
You are doing this too much time, just having it destroyed at the end of the public is not a bad thing and far from beeing bad, in any ways. About resources consumption, the var declared inside the loop will use more memory than the one declared outside.

Quote:
After all this, I would conclude that there is no major difference (but the difference is there) in both the cases. It is the choice of a person whether he wants to create the variables inside or outside the loops, but one should prefer them to be declared outside.
As I said above, we should keep using "the good way" and to keep the good practices. Your advice will confuse the beginners, and imagine this: a plugin that declare variable inside the loop is approved, because, HEY, it doesn't really matter, it won't use much more resources. A beginner use that code as reference, but he has a bigger loop where it matter if he declare outside/inside. What you will tell him ? He will simply say that if the approved plugin use this is fine, and in most cases, even if you explain the difference and why it is so, he will refuse to understand.

It should not hurt if you do things in the proper way.
__________________

Last edited by HamletEagle; 11-04-2014 at 10:15.
HamletEagle is offline
GuskiS
Veteran Member
Join Date: Aug 2007
Location: Latvia
Old 11-04-2014 , 10:16   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #6

Quote:
Originally Posted by HamletEagle View Post
PHP Code:
first examplequote broke itlol 
Arkshine's way is better.
__________________
Finished mods:
Trouble in Terrorist Town
MurderMod
The Hidden
Cowboys vs Indians
JailBreak Supreme
Survival Madness

Last edited by GuskiS; 11-04-2014 at 10:18.
GuskiS is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 11-04-2014 , 10:20   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #7

That's not about memory used, but how it's managed. In Pawn, each new variable is zeroed, so with an array[1000] and in a loop, it allocates/frees each time the array and zero it ; that's something you should avoid as it's an expensive operation.
__________________
Arkshine is offline
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 11-04-2014 , 10:22   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #8

Quote:
Originally Posted by GuskiS View Post
Arkshine's way is better.
You just didn't get what I mean. I was speacking about another variable, not the loop iterator...
Code:
new var for(new i; i < x; i++ ) {     var++ } //and for(new i; i < x; i++ ) {     new var     var ++ }

Maybe now it's more clear.
__________________

Last edited by HamletEagle; 11-04-2014 at 10:25.
HamletEagle is offline
GuskiS
Veteran Member
Join Date: Aug 2007
Location: Latvia
Old 11-04-2014 , 10:38   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #9

I'm saying that Arkshine's way is better:
Code:
new var;
for(new i; i < x; i++ )
{
     var++;
}

//to

for(new var, i; i < x; i++ )
{
     var++;
}
It is different
__________________
Finished mods:
Trouble in Terrorist Town
MurderMod
The Hidden
Cowboys vs Indians
JailBreak Supreme
Survival Madness

Last edited by GuskiS; 11-04-2014 at 10:39.
GuskiS is offline
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 11-04-2014 , 10:43   Re: [FAQ] Whether to create variables inside/outside loops
Reply With Quote #10

You didn't understand that "i" was the loop iterator, and that the variable called "var" was just a random variable that will do something different from the iterator. Maybe a more clear example:

Code:
new var = 4     for( new i; i < 15; i++ )     {         if( i < var )         {             server_print("Something")             var = i         }     }
This is what my first example was about.

Also your example is wrong, you are using the iterator i that is never declared.
I will just stop now, I fell like it's enough and that I've wrote my opinion in enough details. I have no reason to argue, just wanted to make what I mean clear.
__________________

Last edited by HamletEagle; 11-04-2014 at 10:46.
HamletEagle is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 03:59.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode