内存管理性能增强
遇到性能问题可以将低效代码转移到更快的本地代码中
垃圾回收策略
触发回收的好时机是加载场景时,当游戏暂停时,再打开菜单界面后的瞬间
unity垃圾回收是使用标记清除来做的
拆箱和装箱
装箱:将值类型转换为引用类型称为装箱
拆箱:将引用类型转换为值类型称为拆箱
class Program
{
static void Main(string[] args)
{
int i = 128;
object obj = i;
obj = 512f;
i = (int)obj;
}
//尝试将obj拆箱到一个不是最新赋值的类型时,将引发
//Unhandled exception. System.InvalidCastException: Unable to cast object of type 'System.Single' to type 'System.Int32'.
}
1.struct是指类型,class是引用类型
public class DamageResult {
public Character attacker;
public Character defender;
public int totalDamageDealt;
public DamageType damageType;
public int damageBlocked;
// etc.
}
public void DealDamage(Character _target) {
DamageResult result = CombatSystem.Instance.CalculateDamage(this,
_target);
CreateFloatingDamageText(result);
}
public struct DamageResult {
// ...
}
//当使用目的是在向程序某处发送数据库,且数据的持续时间不需要超过
//当前作用域,那么可以使用struct来替代
2.数组的区别
TestStruct[] dataObj = new TestStruct[1000];
for(int i = 0; i < 1000; ++i) {
dataObj[i].data = i;
DoSomething(dataObj[i]);
}
However, the following, functionally equivalent, code would not result in any heap
allocations since the struct objects being used are value types, and hence, it would be
created on the stack:
for(int i = 0; i < 1000; ++i) {
TestStruct dataObj = new TestStruct();
dataObj.data = i;
DoSomething(dataObj);
}
void TestFunction() {
string testString = "Hello";
DoSomething(testString);
Console.WriteLine(testString);
//Debug.Log(testString);
}
void DoSomething(string localString) {
localString = "World!";
}
TestFunction();
这个代码还是打印hello
1.通过值传递值类型,只能修改其数据的副本值
2.通过引用传递值类型,可以修改传入的原始数据
3.通过值传递引用类型,就可以修改原始引用的对象
4.通过引用传递引用类型,可以修改原始的引用的对象数据集
3.数据布局的重要
public struct MyStruct {
int myInt;
float myFloat;
bool myBool;
string myString;
}
MyStruct[] arrayOfStructs = new MyStruct[1000];
对比
int[] myInts = new int[1000];
float[] myFloats = new float[1000];
bool[] myBools = new bool[1000];
string[] myStrings = new string[1000];
4.对字典键使用obj.GetInstanceID();
5.unity api中的数组开销
int[] myInts = new int[1000];
float[] myFloats = new float[1000];
bool[] myBools = new bool[1000];
string[] myStrings = new string[1000];
6 foreach巡回会在堆上分配一个Enummerator的类,而不是堆上分
配
7.协程会消耗少量内存,直到调用yield,避免产生太多短信时间的协成
8.闭包很危险,匿名方法和lambda表达式可以是闭包,但不能总是闭包,取决于方法是否使用了它的作用于和参数列表之外的数据
9..net库要少用,比如lINQ和Rehhex类,因为 通用必定减低性能
10.对象池,预制池