笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

CSDN视频网址:http://edu.csdn.net/lecturer/144

Unity引擎优化技术,无非涉及到三点:CPU优化,GPU优化,内存优化。

先谈谈内存优化:大概可以分成三大部分:

1、 Unity3D内部的内存

2、 Mono的托管内存

3、 引入的DLL或者第三方DLL所需要的内存。

其中Unity3D内部的内存包括如下:

  • 资源:纹理、网格、音频等等
  • GameObject和各种组件。
  • 引擎内部逻辑需要的内存:渲染器,物理系统,粒子系统等等
   我们接下来通过代码执行的时间方式给读者介绍一下关于组件的使用效率问题,代码如下所示:
using UnityEngine;

public class CachedMB : MonoBehaviour
{

	Transform _transform;
	public Transform transform
	{
		get { return _transform ?? (_transform = base.transform); }
	}

	//for testing
	public Transform uncachedTransform
	{
		get { return base.transform; }
	}

	Rigidbody _rigidbody;
	public Rigidbody rigidbody
	{
		get { return _rigidbody ?? (_rigidbody = base.GetComponent<Rigidbody>()); }
	}

	Camera _camera;
	public Camera camera
	{
		get { return _camera ?? (_camera = base.GetComponent<Camera>()); }
	}

	Light _light;
	public Light light
	{
		get { return _light ?? (_light = base.GetComponent<Light>()); }
	}

	private Animation _animation;
	public Animation animation
	{
		get { return _animation ?? (_animation = base.GetComponent<Animation>()); }
	}

	private ConstantForce _constantForce;
	public ConstantForce constantForce
	{
		get { return _constantForce ?? (_constantForce = base.GetComponent<ConstantForce>()); }
	}

	private Renderer _renderer;
	public Renderer renderer
	{
		get { return _renderer ?? (_renderer = base.GetComponent<Renderer>()); }
	}

	private AudioSource _audio;
	public AudioSource audio
	{
		get { return _audio ?? (_audio = base.GetComponent<AudioSource>()); }
	}

	private GUIText _guiText;
	public GUIText guiText
	{
		get { return _guiText ?? (_guiText = base.GetComponent<GUIText>()); }
	}

	private GUITexture _guiTexture;
	public GUITexture guiTexture
	{
		get { return _guiTexture ?? (_guiTexture = base.GetComponent<GUITexture>()); }
	}

	private NetworkView _networkView;
	public NetworkView networkView
	{
		get { return _networkView ?? (_networkView = base.GetComponent<NetworkView>()); }
	}

	private Collider _collider;
	public Collider collider
	{
		get { return _collider ?? (_collider = base.GetComponent<Collider>()); }
	}

	private HingeJoint _hingeJoint;
	public HingeJoint hingeJoint
	{
		get { return _hingeJoint ?? (_hingeJoint = base.GetComponent<HingeJoint>()); }
	}

	private ParticleEmitter _particleEmitter;
	public ParticleEmitter particleEmitter
	{
		get { return _particleEmitter ?? (_particleEmitter = base.GetComponent<ParticleEmitter>()); }
	}

	private ParticleSystem _particleSystem;
	public ParticleSystem particleSystem
	{
		get { return _particleSystem ?? (_particleSystem = base.GetComponent<ParticleSystem>()); }
	}

	private GameObject _gameObject;
	public GameObject gameObject
	{
		get { return _gameObject ?? (_gameObject = base.gameObject); }
	}

	private string _tag;
	public string tag
	{
		get { return _tag ?? (_tag = base.tag); }
		set { _tag = value; base.tag = value; }
	}

	private string _name;
	public string name
	{
		get { return _name ?? (_name = base.name); }
		set { _tag = value; base.tag = value; }
	}

}

接下来开始写测试代码案例:

using UnityEngine;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;

public class CacheTest : CachedMB
{
	const int ITERATIONS = 1000000;
	// Use this for initialization

	Transform cached;

	IEnumerator Start()
	{
		cached = uncachedTransform;

		for (; ; )
		{
			yield return null;
			if (!Input.GetKeyDown(KeyCode.T)) continue;

			var sw1 = Stopwatch.StartNew();
			{
				Transform trans1;
				for (int i = 0; i < ITERATIONS; i++)
					trans1 = GetComponent<Transform>();
			} sw1.Stop();

			var sw2 = Stopwatch.StartNew();
			{
				Transform trans2;
				for (int i = 0; i < ITERATIONS; i++)
					trans2 = transform;
			} sw2.Stop();

			var sw3 = Stopwatch.StartNew();
			{
				Transform trans3;
				for (int i = 0; i < ITERATIONS; i++)
					trans3 = cached;
			} sw3.Stop();

			var sw4 = Stopwatch.StartNew();
			{
				Transform trans4;
				for (int i = 0; i < ITERATIONS; i++)
					trans4 = uncachedTransform;
			} sw4.Stop();

			UnityEngine.Debug.LogWarning(ITERATIONS + " iterations");
			UnityEngine.Debug.LogWarning("GetComponent " + sw1.ElapsedMilliseconds + "ms");
			UnityEngine.Debug.LogWarning("MonoBehaviour " + sw4.ElapsedMilliseconds + "ms");
			UnityEngine.Debug.LogWarning("CachedMB " + sw2.ElapsedMilliseconds + "ms");
			UnityEngine.Debug.LogWarning("Manual Cache " + sw3.ElapsedMilliseconds + "ms");
		}
	}
}

执行结果如下所示:



通过显示的结果,我们知道,GetComponent是比较耗费时间的,在游戏开发中尤其是在每帧调用中少用。Manual Cache是耗费时间最少的,应该在游戏开发中尽量多用。
  


Unity内存优化技术测试案例的更多相关文章

  1. Unity内存优化

    [Unity内存优化] 1.在Update方法或循环中,少用string类,因为string类的每次操作都会调用new生成新字符串对象.用StringBuilder代替string,StringBui ...

  2. Unity内存优化(贴图层面)

    聊聊近况: 距离上一篇文章已经过了好久,主要原因是我懒了.公司项目也到了开始优化的阶段,上网找的资料,看过了就忘.还是想把它整理一下,写出来.其实我说的东西,网上都有,我只是搬运工而已. 贴图压缩: ...

  3. Unity内存优化之视频讲解

    视频为中文讲解,mp4格式,大小3.05GB 目录   扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop135452397.taobao.com/ 联系店主

  4. Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术

    转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...

  5. Unity教程之再谈Unity中的优化技术

    这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体   这一步主要是为了针对性能瓶颈中的”顶点 ...

  6. 【Unity技巧】Unity中的优化技术

    http://blog.csdn.net/candycat1992/article/details/42127811 写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得 ...

  7. Unity堆内存优化

    unity中减少堆内存分配以减少垃圾回收处理:只有局部变量且为值类值的变量是从stack栈中分配内存,其它所有情况都是从heap堆中分配内在.* 缓存获取到的数据.* 频繁被调用的函数中尽量少的分配空 ...

  8. Unity中的优化技术

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/candycat1992/article/ ...

  9. 【MDCC技术大咖秀】Android内存优化之OOM

    大神分析的很全面,所以就转过来保存一份,转自:http://www.csdn.net/article/2015-09-18/2825737/1 以下为正文: Android的内存优化是性能优化中很重要 ...

随机推荐

  1. RocEDU.阅读.写作《苏菲的世界》书摘(四)

    亚理斯多德认为,快乐有三种形式.一种是过着享乐的生活,一种是做一个自由而负责的公民,另一种则是做一个思想家与哲学家.接着,他强调,人要同时达到这三个标准才能找到幸福与满足. 亚理斯多德提倡所谓的&qu ...

  2. Zoom Me FAQ

    Q: How to config custom shortcuts? A: Enter the preferences setting window from menu bar "Prefe ...

  3. Centos为mysql开启binlog

    1.查询mysql配置文件所在位置 2.编辑配置文件/etc/my.cnf 在文件尾部添加: log-bin=/var/lib/mysql/mysql-bin server-id=123454  (5 ...

  4. java如何调用接口 2

    在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适,所以,问题来了,java如何调用接口?很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接 ...

  5. CentOS 7 Fail2ban防暴力破解

    1.安装 yum install epel-release -y yum install fail2ban fail2ban-systemd -y 2.配置 //新建配置 vim /etc/fail2 ...

  6. 使用@Named注解绑定多个实现(java,scala)

    版权申明:转载请注明出处. 文章来源:http://bigdataer.net/?p=330 排版乱?请移步原文获得更好的阅读体验 1.背景 最近项目中使用了guice作为依赖注入的框架.碰到一个如下 ...

  7. mysql 的行转列 PIVOT 的使用

    语句:SELECT DataDate , PropertyText , DataValue FROM RPT_ReportProperty p WITH ( NOLOCK ) JOIN RPT_Rep ...

  8. perl I/O和缓存的关系

    最近在查看日志时,突然发现信息没有及时写入日志,研究了很久,突然醒悟:原来是print的缓存原因. 顺着这个详细了解了下perl里的IO缓存机制: 1.正常情况下,操作系统的读写都有缓存(buffer ...

  9. thinkphp3.2.3定时任务 不能获取本模块config, 不能获取本模块的其他配置

    一开始创建就有一个home模块再创建一个Data模块 定时任务在/Application/Common/Conf/crons.php中,这里不讲怎么创建定时任务. Data模块的配置文件路径如下/Ap ...

  10. 【Python】学习笔记之列表生成式

    列表生成式 主要用于生成较为复杂的列表 常用用法 >>> [x * x for x in range(5) if x % 3 !=1 ] [0, 4, 9] #返回除以3余数不为1的 ...