找回密码
 立即注册
查看: 200|回复: 0

Unity性能分析1

[复制链接]
发表于 2022-12-21 09:04 | 显示全部楼层 |阅读模式
话不多说直接开始



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赋值

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-27 07:27 , Processed in 0.116069 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表