Unity3D的Delegate和SendMessage的性能差测试,以及Delegate在多线程使用要注意的小问题

一、回顾前面写的关于Delegate的消息传送优化文章,http://blog.csdn.net/chiuan/article/details/7883449 

下面的代码是做一个简单的Delegate和SendMessage之间的优化性能差距测试:

using UnityEngine;
using System.Collections;
/// 
/// Delegate basic.
/// just test Delegate && SendMessage ..
/// 
/// By Chiuan 2012.8
/// 
public class DelegateBasic : MonoBehaviour {
	
	//define my delegate statement.
	public delegate void MyDelegate(string arg1);
	
	//create my delegate object
	public MyDelegate myDelegate;
	
	//need some values to debug time spent.
	bool isStart;
	float timeStart;
	int count;
	
	bool isStartSendMessage;
	
	// Use this for initialization
	void Start () {
		myDelegate += myFunciton1;
		//myDelegate += myFunciton2;
	}
	
	// Update is called once per frame
	void Update () {
		if(isStart )
		{
			isStart = false;
			count = 0;
			timeStart = Time.realtimeSinceStartup;
			Debug.Log("Start = " + timeStart );
			for(int i= 0; i< 50000;i++)
			{
				if(myDelegate != null) myDelegate("");
			}
		}
		
		if(isStartSendMessage)
		{
			isStartSendMessage = false;
			count = 0;
			timeStart = Time.realtimeSinceStartup;
			Debug.Log("Start = " + timeStart );
			for(int i= 0; i< 50000;i++)
			{
				this.gameObject.SendMessage("myFunciton1","",SendMessageOptions.DontRequireReceiver );
			}
		}
	}
	
	
	void OnGUI()
	{
		if(GUILayout.Button("INVOKE Delegate"))
		{
			isStart = true;
		}
		
		if(GUILayout.Button("SendMessage"))
		{
			isStartSendMessage = true;
		}
		
	}
	
	void myFunciton1(string s)
	{
		count++;
		if(count == 50000)
		{
			Debug.Log("End = " + Time.realtimeSinceStartup );
			Debug.Log("Time Spent = " + ( Time.realtimeSinceStartup - timeStart ) );
		}
	}
	
	void myFunciton2(string s)
	{
		//Debug.Log("myFunciton2 " + s);
	}
	
	
}

大概快个10倍的样子,频繁调用和响应其他方法的时候,我们得使用Delegate的委托事件取代SendMessage。


二、在多线程Thread下使用Delegate要注意

1、我们应该知道Monobehaviour提供的一些快捷的API去调用,例如:FindObjectOfType,GameObject.Find,SendMessage,StartCoroutine……等等。

如果在其他线程去调用这些的话,那么我们肯定会遇到错误的提示,提示这些方法只能在Mainthread中调用,请把它们的构造方法放到Awake或者Start。如果是Delegate在多线程中响应了相关方法,要去启动一个Coroutine,那么绝对会报错的。

为什么呢?

1.1、记住Unity3D是有一个单线程程序,就是它有一个主线程处理各种UnityEngine中的MonoBehaviour 便捷的查找方式都只能在默认的主线程中去调用。(我的项目就涉及到多线程处理数据的问题,就遇到这种莫名其妙的错误,因为Delegate委托代理者和方法是分开的,写主线程的方法很容易会带有MonoBehaviour里U3D自带的API,目前我发现要在其他线程启动一个协程确实不太好使)


2、在Thread中的Delegate响应去使某个对象,这个对象又是在MonoBehaviour中Awake或者Start初始化的话,很容易造成空引用的错误。




你可能感兴趣的:(Unity3D编程研究与优化)