- Home /
Static variables optimization
There are several quite big static arrays in the different place of code. For example such as: public static someIndexes = new int[1024, 1024];
There is no references on one of them at all. It just not used. Will it be excluded from the final build? Or it will be created in memory at launch anyway?
I switch between them in different projects. Very inconvenient to turn them on and off manually. Also it's possible to forget one. So if there is no optimization I have to write some automation tool and spend unknown time. So better to have optimization :)
Have found good trick to make global #defines here: forum.unity3d.com
There is also a link there on the script to edit global defines.
Unity supports this in the editor now, no need for trickery
Answer by cregox · Jun 25, 2013 at 04:05 PM
I just did a simple test. Creating it as big as possible.
At first, and in my case, using either nothing or [9999][9999]
would yield to no difference. Even the profiler showed nothing. Going 1 higher to [99990][99990]
already proved to be no good. Can't even compile. Say "OutOfMemoryException: Out of memory". I created it as such:
public class Test : MonoBehaviour {
static int[,] bigVar = new int[9999,9999];
}
Then I deduced that, as expected, it is created even if not being used. If you can pass through the initialization, no difference is noticed because it's not being used. But, as it turns out, it's not that simple.
On a second test, thanks to @MorphingDragon's insight, there was no error at all. No matter how big I set it:
public class Test : MonoBehaviour {
static int[,] bigVar;
void Start () {
bigVar = new int[999999,999999];
}
}
Garbage collector only acts at run time (and I thought it would not touch static variables, but I was wrong there). The compiler couldn't filter it out at first, even if not being used, most likely because of how it was initiated (don't ask me why).
So, just initiate it on Start
or Awake
and you'll be fine! ;-)
Static has nothing to do if a statement is evaluated at runtime or not, it only means a construct is associated with a class ins$$anonymous$$d of an instance. The garbage collector will still act on static variables.
readonly and const however do effect when statements are evaluated. A const variable will be evaluated at compile time and essentially will copy that variable as a constant throughout your code. A readonly variable will be evaluated at runtime. You can effectively get it to wrap method calls as variables.
Eg --- private readonly GameController gc_ = GameController.GetInstance();
I beg the different @$$anonymous$$orphingDragon: http://stackoverflow.com/questions/6600093/do-static-members-ever-get-garbage-collected
In that link he's only modifying the instance variables. Yes what that guy says is true and the compile time instantiated static objects will never be destroyed. However any runtime created objects will be destroyed even if they are on a static reference. What I meant is if you modified the static reference the GC will still walk it and remove the objects associated still live on the heap. Since Unity mono version uses a conservative GC you may have to encourage it a little to make it walk the static variables. Because of this, an optimization technique is to never create static variables at compile time, but to create them lazily at runtime so they are collected if needed. (and they don't use memory if they're not needed!)
using UnityEngine;
using System.Collections;
public class GC : $$anonymous$$onoBehaviour {
static int[] arr;
// Use this for initialization
void Start () {
}
void OnGUI()
{
if(GUI.Button(new Rect(0, 0, 100, 100), "CREATE ARRAY"))
arr = new int[10000000];
if (GUI.Button(new Rect(100, 0, 100, 100), "DESTORY ARRAY"))
arr = null;
}
// Update is called once per frame
void Update () {
}
}
Indeed. With your example, I just did few more testing, and there is more to it... I'll edit the answer.
Answer by MorphingDragon · Jun 25, 2013 at 02:48 PM
Most compilers will remove statements without side effects in the optimization stage. Mono is no different AFAIK. If you have unused variables they will most likely be trimmed.
Another example is loops with nothing in them or modifying a variable that is never used. They will simply be removed and replaced with an "Identity". You can play with a C compiler and look at its generated assembly if you want an idea of what a compiler will do for you.
Well, on my tests I'd say it's not that simple... But I don't quite follow why.
That's why I suggest playing to see what compilers actually generate rather than relying on the profiler. A computer can't execute code that isn't there.
Your answer
Follow this Question
Related Questions
My static variable changes, but other scripts don't notice. 3 Answers
passing variables through scripts 0 Answers
Can one use of a static variable, change it globaly? 2 Answers
How can I edit my static variable in the editor? 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers