|
话不多说直接开始
Unity版本
测试硬件配置
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using TestAsyncMdl;
using UnityEngine;
using UnityEngine.UI;
public class TestAsync : MonoBehaviour
{
private Text mTxt;
private Vector3 mVector3;
private float mFloat;
public int LoopNum=10000;
public EFunType mEFunType;
private MyVector3 mMyVector3;
// Start is called before the first frame update
void Start()
{
mTxt=gameObject.GetComponent<Text>();
}
private int index;
// Update is called once per frame
void Update()
{
for (int i = 0; i < LoopNum; i++)
{
index += 1;
switch (mEFunType)
{
case EFunType.None:
break;
case EFunType.SetPos0:
SetPos0();
break;
case EFunType.SetPos1:
SetPos1();
break;
case EFunType.SetPos2:
SetPos2();
break;
case EFunType.SetPos3:
SetPos3();
break;
case EFunType.SetPos4:
SetPos4();
break;
case EFunType.SetPos5:
SetPos5();
break;
case EFunType.SetPos6:
SetPos6();
break;
case EFunType.SetPos7:
SetPos7();
break;
case EFunType.SetPos8:
SetPos8();
break;
case EFunType.SetPos9:
SetPos9();
break;
}
}
}
private void SetPos0()
{
}
private void SetPos1()
{
index += 1;
index += 1;
index += 1;
index += 1;
index += 1;
index += 1;
index += 1;
index += 1;
index += 1;
index += 1;
}
private void SetPos2()
{
SetPos0();
}
private void SetPos3()
{
mTxt.transform.position = new Vector3(index, mTxt.transform.position.y, mTxt.transform.position.z);
}
private void SetPos4()
{
mTxt.transform.position.Set(index, mTxt.transform.position.y, mTxt.transform.position.z);
}
private void SetPos5()
{
mFloat = mTxt.transform.position.x;
}
private void SetPos6()
{
mFloat = index;
}
private void SetPos7()
{
mFloat = mMyVector3.x;
}
private void SetPos8()
{
mMyVector3.x = mVector3.x;
}
private void SetPos9()
{
mVector3 = mTxt.transform.position;
}
}
public struct MyVector3
{
public float x;
public float y;
public float z;
public void Set(float newX, float newY, float newZ)
{
this.x = newX;
this.y = newY;
this.z= newZ;
}
}
public enum EFunType
{
None,
SetPos0,
SetPos1,
SetPos2,
SetPos3,
SetPos4,
SetPos5,
SetPos6,
SetPos7,
SetPos8,
SetPos9,
}
可以看到一个switch和一个加法的耗时只有0.06-0.07这是及其低的
调用一个空函数耗时竟然有1.2左右,而且函数内的消耗有0.5左右
试试调用一个含有10个加法的函数,函数耗时来到0.62左右,也就是一个空函数约是50个加法的耗时
并且得出一个加法的耗时约等于0.01毫秒
一个嵌套空函数,耗时几乎翻倍!再次确认调用一个空函数的大概耗时
new Vector3赋值的耗时是锯齿状的,峰值是28,低值是17左右,排除其他消时约是加法的1500-2500
而直接set的消耗约等于new Vector3赋值的谷值,约是加法的1500倍
我们会发现两个很有意思的问题
(1)new Vector3 性能消耗除峰值是跟直接set一样的
(2)new Vector3 里峰值的消耗,Unity是检测不出来的
其实在函数内声明一个值类型的局部变量,数据是发生在栈里,所以Unity无法检测到。系统自动管理栈内的局部变量,所以不会有额外的GC,但是会有额外释放消耗。
再往下看,我们试试set一个float会有多大的消耗
给一个浮点数赋值耗时竟然达到7,这非常可怕,一个加法的700倍左右!
我们再试试自定义的浮点数,发现其实并不是如此!修改一个浮点数的性能消耗极低
再试试自己写的结构体,发现性能消耗也是非常低,几乎可以忽略不计
尝试修改Unity封装的Vector3发现耗时非常低
再试试直接给transform.position赋值,耗时来到5毫秒左右约是加法的500倍
在Unity源码中看到了一层封装,可惜是无法访问的没办法看到其源码,由此找出set position的额外消耗
测试总结:
(1)空函数的调用并不是免费的,性能消耗大概是修改一个整型或整型加法的50倍左右
(2)声明一个值类型的局部变量不会产生GC,但是会有额外性能消耗。
(3)修改一个结构体的参数性能不会几乎没有额外消耗
(4)修改transform.position的参数性能消耗极大!谨慎使用,可以的情况下先用其他数据结构完成计算,最后再给transform.position赋值 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|