Search Unity

Declaring variables and loop

Discussion in 'Scripting' started by AkilaeTribe, Aug 23, 2010.

  1. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    Greetings,

    is there a difference between

    Code (csharp):
    1. function Update ()
    2. {
    3.     if (canMove)
    4.     {
    5.         var direction : Vector3;
    6.         var nearestBlock : Transform;
    7.        
    8.         direction = GetDirection ();
    9.         nearestBlock = GetNearestBlockInDirection (direction);
    10.     }
    11. }
    and

    Code (csharp):
    1. var direction : Vector3;
    2. var nearestBlock : Transform;
    3.  
    4. function Update ()
    5. {
    6.     if (canMove)
    7.     {
    8.         direction = GetDirection ();
    9.         nearestBlock = GetNearestBlockInDirection (direction);
    10.     }
    11. }
     
  2. dbp

    dbp

    Joined:
    Mar 3, 2010
    Posts:
    324
    the biggest difference you should be aware of is that in the latter case you can also use the variables in any other function in that script, for example the Start() function or OnTriggerEnter() or whatever you use.
    performance-wise i think the latter would also be faster, but i could be wrong there.
     
  3. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    I know that declaring a variable inside a function make it so it only live inside it. But I was asking questions about the "behind the scene" stuff : is the game creating a new variable each time the function is called, or is it reusing the same variable (in the memory, I mean) ? :wink:
     
  4. giyomu

    giyomu

    Joined:
    Oct 6, 2008
    Posts:
    1,094
    if i don't say stupid things ^^,

    create variable like the first case may allocate memory at run time , which is not what you may want performance wise ...
     
  5. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    As mentioned, declaring the variables in the loop will allocate more memory temporarily. The garbage collector will eventually clean them up though. Additionally, there may be a very minor processing overhead of allocating the memory.

    But honestly, this is pretty inconsequential. Program it the way that makes the most logical sense for ease of development and maintenance. Worry about such optimizations later.
     
  6. JRavey

    JRavey

    Joined:
    May 12, 2009
    Posts:
    2,377
    The second one is better. In an individual object, the difference would be negligible, but in a game with many objects the problem would grow.

    In the first one, you are instantiating and and destroying a variable in every update. Allocating memory is not free, freeing memory is not free. As for allocating memory at runtime being possibly bad, it is not. You are already allocating the memory because update is being called, so you cannot avoid allocating it and instead should allocate it under conditions which lead to better performance.

    Maybe there is a difference in values, but I cannot agree one iota with FizixMan about "optimizing it later". If you can do it in an efficient way the first time, do it right the first time. Going back over your application and trying to optimize it after the fact will produce results far worse than iterative optimization throughout the application's development cycle. In business applications, where minor delays are not noticed by users, you can get away with a lot of lazy programming; games do not have that luxury, poor performance immediately lowers the enjoyability.

    What kind of game is this, if you don't mind my asking?
     
  7. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    To be short : it is a puzzle and racing game. The player must go from the starting point to the end point within the limited time. The circuit is made of colored blocks, and the player goes from blocks to blocks.

    The more the player chains blocks of the same color, the more he increases his synchronization bar.

    The more the synchronization bar is high, the more points he earns for each additional move.

    If the player repeatedly chains block of different colors, he risks losing a bit of his synchronization bar.

    If his synchronization bar goes below zero, the race is over.

    The player avatar is a kind of gyroscope with only two gimbals.



    It explains the name of the functions (get direction of the move, and retrieve the nearest block in that direction ;)).

    Your opinion ? :)

    By the way, thanks you all for your answer. I will keep in mind the pro and cons of declaring variables : doing that is more suited for irregular executions.
     
  8. JRavey

    JRavey

    Joined:
    May 12, 2009
    Posts:
    2,377
    It sounds interesting, but different enough that I am not comfortable commenting on my impression without seeing it in action or at least having a better understanding.
     
  9. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    I am currently working on a prototype, stay tuned ;)
     
  10. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    JRavey, I have to disagree with you. No offense to anyone here, but many Unity developers are not seasoned, hardcore professional programmers. (which is perfectly fine, we all have to start somewhere!) I think the vast majority of them should focus on clean, readable code that they can learn and improve from and not sacrifice that to focus on tiny little things like this. To sum up:
    http://en.wikipedia.org/wiki/Program_optimization#Bottlenecks
    http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize

    That's just my opinion, and I think it would serve you best AkilaeTribe. Once you got the game under your belt and it's running, go back over and review your code. Figure out what to optimize then, the best way to do that, and learn from it for the future or version 2.0 of your game!
     
  11. JRavey

    JRavey

    Joined:
    May 12, 2009
    Posts:
    2,377
    That sounds good on paper, but my recommendation requires so little effort that it could hardly be called optimization. I would probably downgrade it into "decent programming practices." If one is not a good programmer, they should pick the low hanging fruit when possible and use their allowance for inefficiencies on complicated problems instead.

    Either way, the OP asked if there is a difference. There is a large difference in those two methods relative to the size of the functions. It would be unfair to say, "Yes, there is a difference" and leave it at that. By asking if there is a difference, the OP is implicitly asking "and if there is a difference, how are they different?"
     
  12. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    In this case, the only difference of real consequence is elevating the scope of the variables. If you were looping on this tens of thousands of times per second, then it may be a worthwhile optimization.

    Yes, your recommendation requires so little effort in this case, but if this coding practice was applied liberally across the application it would cause undue clutter and complexity to their (most likely already unnecessarily cluttered and complex) code.

    I think we answered, at length, the difference already. Now the conversation has evolved to which version to use, why, and is that justified?
     
  13. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    This thread is full of incorrect information.

    First of all, the local variables in the first snippet are created on the stack and not in main memory, which means the allocation is pretty much free and garbage collector does not have to clean it up at all. Second of all, there is no instantiation of any kind going on in the variable declarations so there is no overhead involved there either (unless instantiation happens in one of the function calls, but those are part of the function in both snippets).

    Furthermore, the difference in speed between local and global variable access is microscopic compared to things like rendering your scene, physics, etc. Even on the iPhone, it will be hard to gain any measurable advantage from switching from one to the other in an actual game.

    And finally, most people in this thread claim that global variables are faster, which (presumably due to cache behaviour) is contradicting measurements done by eric in this thread:
    http://forum.unity3d.com/viewtopic.php?t=43631&highlight=local+global+variables

    He concludes local variables are actually 20% faster. Anyway, that information is irrelevant: use global variables when you need access to them from other functions, use local variables if you need them only locally.
     
  14. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Thanks tomvds. I actually feel kind of like an idiot now rereading the thread and the snippets. :D I need more morning coffee.
     
  15. dbp

    dbp

    Joined:
    Mar 3, 2010
    Posts:
    324
    from reading your posts i get the impression that fast code equals complex and un-readable code. though, it's often small things like this that make your code faster and many times even cleaner at the same time.
    optimizing your code after you have a running game is what creates messy code, especially if you are a beginner.
    worrying about this kind of stuff is a good attitude as a beginning programmer in my opinion and it will help understanding what goes on "behind the scenes" much better.
     
  16. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Indeed, many times the simplest, most readable code is already in a very fast, optimized state. When you write good, clean code usually you get a fairly efficient result. This is philosophy I take; I never sacrifice code cleanliness for performance until it's done, bug-free, and I can benchmark the bottlenecks.

    In the code snippets provided, "direction" and "nearestBlock" are being promoted to class members. Unless this has an actual architectural purpose in your API, I don't think it should be done as it adds unnecessary clutter.
     
  17. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    Currently, they are in the Update function, but when I think about future features, I may have to put them as local variable. It will depend on how I will implement those features ;)

    From what I understood, declaring variables inside functions uses a kind of memory called the "stack" and is very fast and easy to clean and access. It is however limited in size, and trying to use more slots than available leads to crash.

    So, as long as it do not crash, it is alright ? ;)
     
  18. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Indeed. In practice, you will never run out of stack, though. (With the exception of making silly mistakes in recursive functions, but then your program is incorrect anyway).
     
  19. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Do not worry about crashing the stack. It will be managed by Unity just fine. The only thing you have to be concerned about is going into infinite loops:
    Code (csharp):
    1. function Test()
    2. {
    3.     Test();
    4. }
    This will quickly cause a stack overflow. You can also get it through heavily nested functions (say for tree structures), but if that's the case you'd want to rewrite your recursion logic anyway to avoid that. From the sounds of it, you probably won't have to worry about that.

    EDIT: damn you tomvds! Beat me to it.
     
  20. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    Acknowledged ! I will keep everything in mind. Thanks you all ! ;)