- Home /
Script Performance: 1 central or many independent?
I have been doinig this in the past:
// main script C#
public Text v1;
public Text v2;
public Text v3;
public Text v4;
// and so on...
void Update () {
v1.text = "v1: " + PlayerPrefs.GetInt ("v1");
v2.text = "v2: " + PlayerPrefs.GetInt ("v2");
v3.text = "v3: " + PlayerPrefs.GetInt ("v3");
v4.text = "v4: " + PlayerPrefs.GetInt ("v4");
// and so on...
// I know I could use a for loop, but that's not the point of the question.
}
Should I switch to this?
// script found on all of the text objects C#
public string name;
private Text t;
void Start () {
t = transform.GetComponent <Text> ();
}
void Update () {
t.text = name + ": " + PlayerPrefs.GetInt (name);
}
The first example seems performance heavy to me because the script executes all of the time, no matter if the children are active. But then again, I read somewhere that 1 update
with heavy tasks is better than many updates
with the heavy tasks spread out.
In the same way, it's easier to render an object with 1000 meshes than 1000 objects with 1 mesh each.
Which way should I go?
Answer by fafase · Jul 02, 2015 at 11:15 AM
A does it all in one place while B does it all independently.
A will quickly become impossible to maintain as you are about to add lines after lines while B is clear of doing only what it should.
There is a little cost for having many updates since each call means stacking data, processing the code, and unstacking.
Forget about that last line.
Answer by _Yash_ · Jul 02, 2015 at 11:05 AM
Both are equally heavy operations. i also asked same question here
For this case: You should not use playerprefs in Update, instead cache the data of playerprefs to some static variable when game starts and update it when your game exits or when cpu is being consumed (b/w screen Transitions or when leaving play area...).
I have to get the values every frame because they contain info such as health, score, time, ammo, etc. Should I create a gameobject with a database.cs
script on it and get a reference to it in every other script, so that ins$$anonymous$$d of saying PlayerPrefs.GetInt ("something")
I can say database.something
?
if the value in PlayerPrefs is not changing you might as well get it once in the Start and use it all over:
int prefValue = 0;
void Start(){
preValue = PlayerPrefs.GetInt("something");
}
if that value is updated regularly then create a connection between the script storing and all scripts needing it. Either via a direct reference using GetComponent or via some event/listener pattern.
If you need a value "PlayerPrefs backed" you might want to use a wrapper class like this:
public abstract class PrefVal<T>
{
protected string m_Name;
protected T m_Value;
protected T m_DefaultVal;
protected bool m_Initialized = false;
public abstract void Save();
public abstract void Load();
public PrefVal(string aPrefName, T aDefaultVal)
{
m_Name = aPrefName;
m_DefaultVal = aDefaultVal;
}
public T Val
{
get
{
if (!m_Initialized)
{
Load();
m_Initialized = true;
}
return m_Value;
}
set
{
if (value != m_Value)
{
m_Value = value;
Save();
}
}
}
}
public class PrefIntVal : PrefVal<int>
{
public override void Save ()
{
PlayerPrefs.SetInt(m_Name, m_Value);
}
public override void Load ()
{
m_Value = PlayerPrefs.GetInt(m_Name, m_DefaultVal);
}
public PrefIntVal(string aPrefName, int aDefaultVal) : base(aPrefName, aDefaultVal) { }
}
With that class you can simply define your variable like this;
public class SomeScript : $$anonymous$$onoBehaviour
{
public PrefIntVal v1 = new PrefIntVal("v1", 0);
}
Of course to access the actual value you would use the property of that class:
t.text = v1.Val;
// and to assign a value
v1.Val = 5;
This will automatically save the value whenever it's changed and load it automatically when you read the value the first time.
The generic base class allows you to easily create a string / float version or any other type you want. You just have to implement the actual Save and Load methods in the derived class.
Your answer
