For optimization purposes, I was wondering if I should declare local variables outside functions like Update or OnGUI, to avoid the overhead of declaring the variable again and again every frame.
You ask if there is overhead, there is always some overhead in declaring variables.
As a matter of maintainability, I generally agree with NPSF. Youâre probably better off having that one variable there so it is easier to read and maintain. If there were many thousands of these, you might have to improve the performance of the script.
Good software engineering has to balance clean and maintainable code against performance. Some (bad) programmers will just go entirely for the former suggesting the user throw more hardware at it, some programmers will optimize to the point that nobody can tell what is happening when it is time to find a bug or update the code (which is a real pain). If your organization has well documented coding standards, you wonât have too much trouble knowing when which method is appropriate for a situation.
Let me interject one thing. If you build complex objects, it is best NOT to rebuild them every frame. Things that take a while to build are bad for update functions. If I were concerned about limits I would not build GameObjects every frame, nor meshes. This includes Instantiating. They take a touch of time to build but if you build 500 per frame then your performance will drop significantly.
Does this mean you can never build these in an Update? You can, and often will, just donât do it with reckless abandon. Your game is already instantiating particles and other things it takes to make it look nice.
Things like Intâs and Floatâs would be no problem. Even Vector3âs and Quatâs are not much of a burden. I recently found an HSBColor class. I looked into the code and saw that to build one it took a lot of math to convert a color. I remember thinking, that canât be good. I built it and ran tests on itâs efficiency, itâs not that bad.
This question comes up every once in a while and it is an excellent example of how not to approach performance optimization
Performance optimization begins with measuring.
While the first two replies to your question give excellent advice to stick to whatâs most readable, they both pick option âbâ as the faster of the two. Measuring (as done by Eric in this thread http://forum.unity3d.com/threads/40981-it-is-good-to-declare-variable..ifâŚ) will show that option âaâ is not only more readable, but also slightly faster (at least in ericâs test case). This may seem counter intuitive, but it is caused by the fact that declaring a variable on the stack (which resides in cache and is done for the entire function at once) can be faster than accessing data from a variable which might reside in main memory.
In my opinion, it is best to write your code as readable as possible without any focus on optimization. Only when you find your game is starting to run too slow, measure which parts of your game take the most time and do performance optimization right there, where it counts the most. 9 out of 10 times, the most time consuming process in your game it is not where you thought it would be.
I would estimate the odds of global vs local variable declaration having a noticeable effect on performance to be approximately zero (but please measure to prove me wrong ).
As a general rule if you donât need it outside of the scope then donât declare it outside of that scope. Even if just for the benefits of easier code-writing when using autocomplete/intellisense
i can not thank you enough for your comment. iâve always struggled with this kind of decision before, but from now on i will write the code to be clean and easy to understand and not stress out about minuscule optimizations.
Personally, I draw the line at using the new keyword. For instance new Vector3(), because you are creating an object and destroying it over and over and the garbage collector will work harder. This article is a good read:
As far as being more readable, thatâs pretty much up to the coder. I think those are good practices to get into right away. Some are very easy like using two labels instead of concatenating strings. Why wait till itâs a problem? Your program might be just slightly slower, but stutter because of the garbage collector and annoy the user, or youâll have to go over it with a profiler when you wouldnât have had to.
If you use them only in update so keep them in update or coroutines.
You should keep them locally whatever you can but if you use many new keywords (create reference types) you require to change your design
Actually it is, as Vector3 is a struct but i think any instance would be an object (everything in C# inherits from object class right?) and also when you make an instance of vector3 you can use that 4 functions of object class
I disagree. There are certain best practices for optimization that we should just start off with. Asking if these is one of them, is a good question. Especially for beginners. For example we see new programmers using GetComponent methods inside of update all the time. One does not need to measure if this is a bad idea. Why waste our time when its a known issue and there is a simple solution.
In the 1st line, we donât need to use new. v1 exists as soon as we declare it. In the 2nd line, v2 is a copy of v1, not a reference to it. changing v2.x doesnât affect v1.x.
To be fair, System.String is a class, and strings are all ref types. Theyâre immutable, so they technically behave like a value type when interacted with, but are treated like a ref type when it comes to how they persist in memory⌠well actually thatâs also slightly untrue because several strings (mostly const strings both expllicit and implicit) get their only special block of memory allocated for them as well.
I also take slight issue with @ 's link.
Itâs only examples are really just pointers, interfaces, and generics.
But pointers only work in unsafe mode which is full of all sorts of odd exceptions (and is why the author probably sort of excludes them from their own list).
Interfaces arenât objects⌠because theyâre just type declarations. To say interfaces arenât objects is to say any type declaration isnât an object (unless reflected of course). Nothing is an interface directly, they only are indirectly in that they implement an interface. And if theyâre capable of implementing an interface they themselves are an object as only objects can implement interfaces. You canât instantiate an IFoo, only a Foo which can be treated as an IFoo.
⌠Basically itâs like saying methods arenât objects, or operators arenât objects, or fields arenât objects. Cause they arenât. But thatâs because these things are outside of the idea of a data structure. Theyâre parts of the data structures. Otherwise, that link needs to add quite a few more things to its odd list of things that arenât objects, pretty much consisting of quite a deal of C# syntax. Which I would argue MS was expecting computer science students and professional programmers to understand they didnât mean EVERYTHING when they said everything on such a pedantic level.
And of course generics arenât⌠because thatâs basically runtime templating. Your is not a type⌠itâs the idea that a type will be defined when used. You canât have a âTâ⌠you can only have a âstringâ once âTâ is replaced with âstringâ when itâs JIT compiled (or AOT compiled, or any other compiled). And once that is compiled, whatever the âTâ variable/field/etc is associated with⌠is an object. Itâs basically the interface/method/operator/field argument all over.
At the end of the day the idea that âeverything is an objectâ in C# is that if you have a defined chunk of managed data (which pointers are unmanaged data), that chunk of managed data (the boundary of âchunkâ being defined by any of the known type definitions class/struct/enum/etc) can be treated as an object. In that it can be cast and stored in a field/variable/mechanism typed âobjectâ.
I have never heard MS saying that âin C# everything inherits from the object classâ. Maybe I have missed something.
And Iâm sorry, weâre software developers, to be at least broadly precise is sort of coming with the territory.
This phrase is very far from true and I only argue with this phrase. My link is only a randomly selected example so I donât only tell that heâs wrong, but he gets the idea why heâs wrong.
Unfortunately the English language isnât as strict as programming languages. So try as we might as developers, the English language will forever wiggle away from what we expect it to mean since anyone can interpret it the way they see fit based on their knowledge of the language.
Hence law using such strict usages of language as to needing explicit definitions before entering any description of law. Otherwise the natural state of English wiggles away from the courts.
So as a result trying to wrangle the âeverything is an objectâ down into a pedantic liturgy just becomes tiresome.
At the end of the day⌠the point is, you can cast pretty much everything to the the object type with exceptions in the outer limits of the language such as unsafe mode.
The point is that new Vector3 doesnât make garbage, since itâs a struct, which is a Value-type. Thatâs what firecracker pointed out 8 years ago. Saying that structs are technically Objects is only confusing the issue.
Iâm a little confusing, so value types are not Object unless you use boxing and unboxing? and as lordofduct pointed Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. when it comes to memory management value types will not treat as an object?