Unity中直接使用transform和gameObject的效率测试
2015-05-16 12:06
465 查看
尽信书不如无书,更何况是网上开发者的博客。这里也包含我自己的博客,有的时候回过头来看是有错误的地方,但是我也懒得改了,而且很多时候我们看到的文章还不一定是原始地址,而是被各个网站七转八转的,更加不可能保证准确性。
这里测试了这么一个说法:“不要在脚本中直接使用transform或者gameObject,而应该在一开始缓存成成员变量如_transform和_gameObject来访问。因为前者每次执行的时候都要获取对应的组件,效率低。”
这种说法不能说完全是错误的,但是经过自己的测试明白其原理后,会对这个问题以及与其类似的问题都会有更加清晰的了解。
首先我们使用组件的时候尽量在一开始使用GetComponent缓存到成员变量里面,这个是完全合理的。但是tansform和gameObject如此常用的对象,Unity应该有更好的优化才对。否则就显得太低级了。我测试的结果也确实如此。如果不想看后面的分析,直接看结论就好了。
结论:Unity中直接访问transform效率会比缓存成成员变量慢一点点,这个只有量级非常大的时候才会体现出来。 Unity对transform和gameObject有足够的优化处理,不要自己再模拟Unity写属性来处理,多数情况效率更差。
请看下图:
测试代码是一个简单的transform坐标赋值,循环100w次。
其中Unity属性就是直接访问transform的时间消耗,而缓存的变量就是成员变量版本的。可以看到直接缓存成员变量确实会快一些,但是100w次执行,性能差别也就10%左右。个人感觉这点差别影响不大。是直接使用unity的属性,还是缓存成员变量看个人习惯了。
注意后面两个属性进行判断和属性直接获取变量。我们有可能会“自以为是”的这么写,如果_transform为空,则获取对应组件,否则直接返回成员变量。这种情况就是最慢的“属性进行判断”,这个时候属性会执行相对复杂的逻辑,速度慢就合情合理了。而如果属性直接返回成员变量,其效率是跟直接访问成员变量一致的。
测试代码如下:
using UnityEngine;
using System.Collections;
public class TestTransform : MonoBehaviour {
private GameObject _go;
private Transform _tr;
protected Transform SimpleTr
{
get
{
return _tr;
}
}
protected Transform Tr
{
get {
if (_tr == null) {
_tr = transform;
}
return _tr;
}
}
protected GameObject SimpleGo
{
get
{
return _go;
}
}
protected GameObject Go
{
get {
if (_go == null) {
_go = gameObject;
}
return _go;
}
}
void Start ()
{
_go = gameObject;
_tr = transform;
DoTestTransform();
DoTestGameObject();
}
public void DoTestTransform()
{
int count = 1000000;
transform.position = Vector3.zero;
int time = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
transform.position = Vector3.one * index;
}
Debug.Log("Unity属性: " + (System.Environment.TickCount - time) * 1000);
_tr.position = Vector3.zero;
int time2 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
_tr.position = Vector3.one * index;
}
Debug.Log("缓存的变量: " + (System.Environment.TickCount - time2) * 1000);
Tr.position = Vector3.zero;
int time3 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
Tr.position = Vector3.one * index;
}
Debug.Log("属性进行判断:" + (System.Environment.TickCount - time3) * 1000);
SimpleTr.position = Vector3.zero;
int time4 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
SimpleTr.position = Vector3.one * index;
}
Debug.Log("属性直接获取变量: " + (System.Environment.TickCount - time4) * 1000);
}
public void DoTestGameObject()
{
int count = 1000000;
gameObject.transform.position = Vector3.zero;
int time = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
gameObject.transform.position = Vector3.one * index;
}
Debug.Log("Unity属性: " + (System.Environment.TickCount - time) * 1000);
_go.transform.position = Vector3.zero;
int time2 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
_go.transform.position = Vector3.one * index;
}
Debug.Log("缓存的变量: " + (System.Environment.TickCount - time2) * 1000);
Go.transform.position = Vector3.zero;
int time3 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
Go.transform.position = Vector3.one * index;
}
Debug.Log("属性进行判断:" + (System.Environment.TickCount - time3) * 1000);
SimpleGo.transform.position = Vector3.zero;
int time4 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
SimpleGo.transform.position = Vector3.one * index;
}
Debug.Log("属性直接获取变量: " + (System.Environment.TickCount - time4) * 1000);
}
}
这里测试了这么一个说法:“不要在脚本中直接使用transform或者gameObject,而应该在一开始缓存成成员变量如_transform和_gameObject来访问。因为前者每次执行的时候都要获取对应的组件,效率低。”
这种说法不能说完全是错误的,但是经过自己的测试明白其原理后,会对这个问题以及与其类似的问题都会有更加清晰的了解。
首先我们使用组件的时候尽量在一开始使用GetComponent缓存到成员变量里面,这个是完全合理的。但是tansform和gameObject如此常用的对象,Unity应该有更好的优化才对。否则就显得太低级了。我测试的结果也确实如此。如果不想看后面的分析,直接看结论就好了。
结论:Unity中直接访问transform效率会比缓存成成员变量慢一点点,这个只有量级非常大的时候才会体现出来。 Unity对transform和gameObject有足够的优化处理,不要自己再模拟Unity写属性来处理,多数情况效率更差。
请看下图:
测试代码是一个简单的transform坐标赋值,循环100w次。
其中Unity属性就是直接访问transform的时间消耗,而缓存的变量就是成员变量版本的。可以看到直接缓存成员变量确实会快一些,但是100w次执行,性能差别也就10%左右。个人感觉这点差别影响不大。是直接使用unity的属性,还是缓存成员变量看个人习惯了。
注意后面两个属性进行判断和属性直接获取变量。我们有可能会“自以为是”的这么写,如果_transform为空,则获取对应组件,否则直接返回成员变量。这种情况就是最慢的“属性进行判断”,这个时候属性会执行相对复杂的逻辑,速度慢就合情合理了。而如果属性直接返回成员变量,其效率是跟直接访问成员变量一致的。
测试代码如下:
using UnityEngine;
using System.Collections;
public class TestTransform : MonoBehaviour {
private GameObject _go;
private Transform _tr;
protected Transform SimpleTr
{
get
{
return _tr;
}
}
protected Transform Tr
{
get {
if (_tr == null) {
_tr = transform;
}
return _tr;
}
}
protected GameObject SimpleGo
{
get
{
return _go;
}
}
protected GameObject Go
{
get {
if (_go == null) {
_go = gameObject;
}
return _go;
}
}
void Start ()
{
_go = gameObject;
_tr = transform;
DoTestTransform();
DoTestGameObject();
}
public void DoTestTransform()
{
int count = 1000000;
transform.position = Vector3.zero;
int time = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
transform.position = Vector3.one * index;
}
Debug.Log("Unity属性: " + (System.Environment.TickCount - time) * 1000);
_tr.position = Vector3.zero;
int time2 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
_tr.position = Vector3.one * index;
}
Debug.Log("缓存的变量: " + (System.Environment.TickCount - time2) * 1000);
Tr.position = Vector3.zero;
int time3 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
Tr.position = Vector3.one * index;
}
Debug.Log("属性进行判断:" + (System.Environment.TickCount - time3) * 1000);
SimpleTr.position = Vector3.zero;
int time4 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
SimpleTr.position = Vector3.one * index;
}
Debug.Log("属性直接获取变量: " + (System.Environment.TickCount - time4) * 1000);
}
public void DoTestGameObject()
{
int count = 1000000;
gameObject.transform.position = Vector3.zero;
int time = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
gameObject.transform.position = Vector3.one * index;
}
Debug.Log("Unity属性: " + (System.Environment.TickCount - time) * 1000);
_go.transform.position = Vector3.zero;
int time2 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
_go.transform.position = Vector3.one * index;
}
Debug.Log("缓存的变量: " + (System.Environment.TickCount - time2) * 1000);
Go.transform.position = Vector3.zero;
int time3 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
Go.transform.position = Vector3.one * index;
}
Debug.Log("属性进行判断:" + (System.Environment.TickCount - time3) * 1000);
SimpleGo.transform.position = Vector3.zero;
int time4 = System.Environment.TickCount;
for (int i = 0; i < count; ++i)
{
int index = i % 100;
SimpleGo.transform.position = Vector3.one * index;
}
Debug.Log("属性直接获取变量: " + (System.Environment.TickCount - time4) * 1000);
}
}
相关文章推荐
- mysql使用rand随机查询记录效率测试
- 使用JDBC向MySQL数据库批次插入10W条数据测试效率
- Unity 使用备忘(四) 游戏物体不挂在脚本文件上直接实现Button(Script)脚本文件的Onclick方法
- Unity使用图片实现transform.LookAt功能
- 关于INT、GUID与COMB在使用效率上的测试
- Unity 中 transform.Find()的使用心得
- Unity 使用 Unity 直接编译外部 DLL
- 关于Unity中混合模式、Alpha测试、深度测试、通道遮罩、面剔除的使用----渲染通道通用指令(二)
- 是否能直接使用img对象名字来替代images[索引值]数组呢?测试代码显示:可以。
- 使用unity进行测试驱动开发的方法
- 测试-关于Unity获取子层级内容的几种接口(Transform FindChild, Component GetComponentInChildren,...)
- php中使用mysqli和pdo扩展,测试连接mysql数据库的效率。
- 不使用缓存和不同缓存下程序的效率测试
- Nginx HttpMemcModule和直接访问memcached效率对比测试
- junit 测试spring-test 代码!在项目中运行测试通过,留着以后直接使用
- 也谈谈Unity的transform使用
- Android自定义控件9----scrollTo/scrollBy实现滑动和直接绘制滑动的对比使用demo测试
- Unity中使用委托/事件实现GameObject之间的通信
- 【Unity3D技巧】在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信 (二) : 引入中间层NotificationCenter