小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Unity優(yōu)化大全(十)之 Memory

 kiki的號 2017-06-20
     Mono的托管內(nèi)存的優(yōu)化主要是代碼的優(yōu)化,以下部分是我在網(wǎng)上收集的資料:

1.盡量不要?jiǎng)討B(tài)的Instantiate和Destroy Object,使用Object Pool??纯次抑皩懙囊黄恼戮突径耍?/p>

2.盡量不要再Update函數(shù)中做復(fù)雜計(jì)算,如有需要,可以隔N幀計(jì)算一次。

3.不要?jiǎng)討B(tài)的產(chǎn)生字符串,如Debug.Log("boo" + "hoo"),盡量預(yù)先創(chuàng)建好這些字符串資源。

4.Cache一些東西,在update里面盡量避免search,如GameObject.FindWithTag("")、GetComponent這樣的調(diào)用,可以在Start中預(yù)先存起來。

5.盡量減少函數(shù)調(diào)用棧,用x = (x > 0 ? x : -x);代替x = Mathf.Abs(x)

6.下面的代碼是幾個(gè)GC“噩夢”。

 String的相加操作,會頻繁申請內(nèi)存并釋放,導(dǎo)致gc頻繁,使用System.Text.StringBuilder代替

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">function ConcatExample(intArray: int[]) {  
  2.   
  3.                var line = intArray[0].ToString();  
  4.                for (i = 1; i < intArray.Length; i++) {  
  5.                                line += ", " + intArray[i].ToString();  
  6.   
  7.                }  
  8.                return line;  
  9. }</span>  

7.在函數(shù)中動(dòng)態(tài)new array,最好將一個(gè)array、傳進(jìn)函數(shù)里修改

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">function RandomList(numElements: int) {  
  2.   
  3.           var result = new float[numElements];  
  4.           for (i = 0; i < numElements; i++) {  
  5.                          result[i] = Random.value;  
  6.           }  
  7.           return result;  
  8. }</span>  

8.function Update() { DoSomeThing(); }

可改為每5幀處理一次:

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">function Update() { if(Time.frameCount % 5 == 0) { DoSomeThing(); } }</span>  

9.定時(shí)重復(fù)處理用 InvokeRepeating 函數(shù)實(shí)現(xiàn)

比如,啟動(dòng)0.5秒后每隔1秒執(zhí)行一次 DoSomeThing 函數(shù):

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">function Start() { InvokeRepeating("DoSomeThing", 0.5, 1.0); }</span>  

10. 優(yōu)化 Update, FixedUpdate, LateUpdate 等每幀處理的函數(shù)

函數(shù)里面的變量盡量在頭部聲明。比如:

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">function Update() { var pos: Vector3 = transform.position; }</span>  

可改為

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">private var pos: Vector3; function Update(){ pos = transform.position; }</span>  

11.主動(dòng)回收垃圾,給某個(gè) GameObject 綁上以下的代碼:

function Update() { if(Time.frameCount % 50 == 0) { System.GC.Collect(); } }

12.優(yōu)化數(shù)學(xué)計(jì)算,比如:如果可以避免使用浮點(diǎn)型(float),盡量使用整形(int),盡量少用復(fù)雜的數(shù)學(xué)函數(shù)比如 Sin 和 Cos 等等。

13.,減少固定增量時(shí)間,將固定增量時(shí)間值設(shè)定在0.04-0.067區(qū)間(即,每秒15-25幀)。您可以通過Edit->Project Settings->Time來改變這個(gè)值。這樣做降低了FixedUpdate函數(shù)被調(diào)用的頻率以及物理引擎執(zhí)行碰撞檢測與剛體更新的頻率。如果您使用了較低的固定增量時(shí)間,并且在主角身上使用了剛體部件,那么您可以啟用插值辦法來平滑剛體組件。

14.減少GetComponent的調(diào)用,使用 GetComponent或內(nèi)置組件訪問器會產(chǎn)生明顯的開銷。您可以通過一次獲取組件的引用來避免開銷,并將該引用分配給一個(gè)變量(有時(shí)稱為"緩存"的引用)。例如,如果您使用如下的代碼:

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">function Update () {  
  2. transform.Translate(0, 1, 0);  
  3. }</span>  

通過下面的更改您將獲得更好的性能:

[javascript] view plain copy
  1. <span style="font-family:Comic Sans MS;">var myTransform : Transform;  
  2. function Awake () {  
  3. myTransform = transform;}  
  4. function Update () {  
  5. myTransform.Translate(0, 1, 0);  
  6. }</span>  

15.避免分配內(nèi)存,您應(yīng)該避免分配新對象,除非你真的需要,因?yàn)樗麄儾辉僭谑褂脮r(shí),會增加垃圾回收系統(tǒng)的開銷。您可以經(jīng)常重復(fù)使用數(shù)組和其他對象,而不是分配新的數(shù)組或?qū)ο?。這樣做好處則是盡量減少垃圾的回收工作。同時(shí),在某些可能的情況下,您也可以使用結(jié)構(gòu)(struct)來代替類(class)。這是因?yàn)?,結(jié)構(gòu)變量主要存放在棧區(qū)而非堆區(qū)。因?yàn)闂5姆峙漭^快,并且不調(diào)用垃圾回收操作,所以當(dāng)結(jié)構(gòu)變量比較小時(shí)可以提升程序的運(yùn)行性能。但是當(dāng)結(jié)構(gòu)體較大時(shí),雖然它仍可避免分配/回收的開銷,而它由于"傳值"操作也會導(dǎo)致單獨(dú)的開銷,實(shí)際上它可能比等效對象類的效率還要低。

16.使用內(nèi)置數(shù)組,內(nèi)置數(shù)組是非??斓?。ArrayList或Array類很容易使用,你能輕易添加元件。但是他們有完全不同的速度。 內(nèi)置數(shù)組有固定長度,并且大多時(shí)候你會事先知道最大長度然后填充它。內(nèi)置數(shù)組最好的一點(diǎn)是他們直接嵌入結(jié)構(gòu)數(shù)據(jù)類型在一個(gè)緊密的緩存里,而不需要任何額外 類型信息或其他開銷。因此,在緩存中遍歷它是非常容易的,因?yàn)槊總€(gè)元素都是對齊的。

[javascript] view plain copy
  1. private var positions : Vector3[];function Awake () {    positions = new Vector3[100];    for (var i=0;i<100;i++)    positions[i] = Vector3.zero;}  

17.使用靜態(tài)類型
當(dāng)使用JavaScript很重要的優(yōu)化是使用靜態(tài)類型替代動(dòng)態(tài)類型。Unity使用一種技術(shù)叫做類型推理的技術(shù)來自動(dòng)轉(zhuǎn)換javascript為靜態(tài)類型腳本。
var foo = 5;
上面例子中的foo將自動(dòng)被推斷為一個(gè)整數(shù)值。因此,Unity可能使用大量的編輯時(shí)間進(jìn)行優(yōu)化,而不使用耗時(shí)的動(dòng)態(tài)名稱變量查找等。這就是為什么Unity的JavaScript執(zhí)行平均速度是其他JavaScript的20倍的原因之一。
唯一的問題是有時(shí)不是所有的東西都能做類型推斷,Unity將會為這些變量重新使用動(dòng)態(tài)類型。通過這樣,編寫JavaScript代碼很簡單,但也會使代碼運(yùn)行速度變慢。
看個(gè)例子:

[javascript] view plain copy
  1. function Start ()  
  2. {  
  3.     var foo = GetComponent(MyScript);  
  4.     foo.DoSomething();  
  5. }  

這里foo將是動(dòng)態(tài)類型,因此呼叫函數(shù)DoSomething必須要較長的時(shí)間,因?yàn)閒oo的類型未知,它必須弄明白是否支持DoSomething函數(shù),如果支持,調(diào)用函數(shù)。
[javascript] view plain copy
  1. function Start ()  
  2. {  
  3.     var foo : MyScript = GetComponent(MyScript);  
  4.     foo.DoSomething();  
  5. }  
這里我們強(qiáng)制foo為指定類型,你將獲得更好的性能。

18.使用#pragma strict
現(xiàn) 在問題是,你通常不會意識到你在使用動(dòng)態(tài)類型。#pragma strict可以解決這個(gè)問題!簡單的添加#pragma strict在腳本頂部,之后Unity將禁用腳本的動(dòng)態(tài)類型,強(qiáng)制你使用靜態(tài)類型。如果有一個(gè)類型未知,Unity將報(bào)告編譯錯(cuò)誤。下面,foo將在編 譯時(shí)報(bào)錯(cuò):
[javascript] view plain copy
  1. #pragma strict  
  2. function Start ()  
  3. {  
  4.     var foo = GetComponent(MyScript);  
  5.     foo.DoSomething();  
  6. }  
19.緩存組件查找
另一個(gè)優(yōu)化是組件緩存。這種優(yōu)化需要一些代碼并且不是總有必要。但是如果你的代碼真的很大,并且你需要盡可能的性能提升,它會是很好的優(yōu)化。
當(dāng)你通過GetComponent獲取一個(gè)組件或一個(gè)變量時(shí),Unity必須從游戲物體里找到正確的組件。這時(shí)你便能通過一個(gè)緩存組件引用到一個(gè)私有變量。
將:
  1. function Update () {  
  2.     transform.Translate(0, 0, 5);  
  3. }  
  4.   
  5. //轉(zhuǎn)換為:  
  6.   
  7. private var myTransform : Transform;  
  8. function Awake () {  
  9.     myTransform = transform;  
  10. }  
  11. function Update () {  
  12.     myTransform.Translate(0, 0, 5);  
  13. }  
后面的代碼運(yùn)行較快,因?yàn)閁nity不用在每一幀尋找變換組件。同樣,支持腳本組件。你可以使用GetComponent獲取組件或其他快捷屬性。

20.如果沒有必要不要調(diào)用函數(shù)
最簡單,最好的優(yōu)化是執(zhí)行最少的工作。如,當(dāng)一個(gè)敵人在遠(yuǎn)處時(shí),讓他處于睡眠狀態(tài),大多時(shí)候是可行的。直到玩家靠近,可以這樣處理:
[javascript] view plain copy
  1. function Update ()  
  2. {  
  3. // Early out if the player is too far away.    if (Vector3.Distance(transform.position, target.position) > 100)  
  4.     return;  
  5.     perform real work work...  
  6. }  
這 并不是很好的方法,雖然Unity不得不在每一幀訪問update函數(shù)。更好的方法是禁用這個(gè)行為直到玩家靠近。有3中方法做這個(gè):使用 OnBecameVisible和OnBecameInvisible。這些調(diào)用與渲染系統(tǒng)相聯(lián)系。一旦攝像機(jī)看到物體,OnBecameVisible 將被調(diào)用,不看他時(shí),OnBecameInvisible被調(diào)用。這有時(shí)很有用。但是對于AI來講通常是沒有用的,因?yàn)槟惚侈D(zhuǎn)敵人,敵人就變成不可用了。
[javascript] view plain copy
  1. function OnBecameVisible () {  
  2.     enabled = true;  
  3. }  
  4.   
  5. function OnBecameInvisible ()  
  6. {  
  7.     enabled = false;  
  8. }  
21.使用觸發(fā)器。一個(gè)簡單的球形觸發(fā)器能引發(fā)驚人效果。你可以調(diào)用OnTriggerEnter/Exit,當(dāng)進(jìn)入你想要的作用范圍。
[javascript] view plain copy
  1. function OnTriggerEnter (c : Collider)  
  2. {  
  3.     if (c.CompareTag("Player"))  
  4.     enabled = true;  
  5. }  
  6.   
  7. function OnTriggerExit (c : Collider)  
  8. {  
  9.     if (c.CompareTag("Player"))  
  10.     enabled = false;  
  11. }  

22.使用協(xié)同程序。Update的問題是他在每幀都發(fā)生。很可能只需要5秒鐘檢查一次玩家的距離。這可以節(jié)約大量的處理周期。

......


最后的最后:

        感覺還有好多沒涉及到,希望大家有好的建議可以再下面留言,相互學(xué)習(xí)哦!奮斗

 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多