unity中链接字符串和变量显示_理解Unity中的优化(六):字符串和文本
字符串和文本:
在Unity項(xiàng)目中,處理字符串和文本經(jīng)常會產(chǎn)生性能問題。在C#中,字符串是不變的。任何對字符串的操作都會重新分配新的字符串,這個代價(jià)是非常昂貴的。如果在多重循環(huán)中重復(fù)地執(zhí)行字符串連接操作,就會造成性能問題,特別是對長的字符串或者大的數(shù)據(jù)集操作的時候。
因此,把N個字符串連接起來就會分配N-1個中間的字符串,這樣連續(xù)的操作就會對堆內(nèi)存產(chǎn)生壓力。
當(dāng)我們需要在多重循環(huán)中或者每一幀對字符串進(jìn)行操作時,記得使用StringBuilder來操作字符串。StringBuilder也還能被重用,以進(jìn)一步減少內(nèi)存的分配。
關(guān)于字符串的使用,詳細(xì)內(nèi)容也可以參考微軟發(fā)布的文檔:Best Practices for Using Strings in .NET?docs.microsoft.com
地域限制和順序比較:
與字符串相關(guān)代碼的一個核心問題就是無意中會使用默認(rèn)的、慢的字符串API。這些API的目的是為了一些商業(yè)化的應(yīng)用,能夠處理出現(xiàn)在文本中的有關(guān)不同文化和語法規(guī)則的字符。
比如,下面的代碼在一些使用美式英語的地區(qū)運(yùn)行時,會返回true。在歐洲地區(qū)運(yùn)行時,返回false。
提示:Unity腳本都是基于美式英語來運(yùn)行的。
對于大多數(shù)的項(xiàng)目,這個完全沒有必要。而且我們簡單對每個字符進(jìn)行比較,判斷兩個字符串是否相等,這速度大約會比使用上面的方式快10倍。當(dāng)然,我們也可以調(diào)用String.Equals方法,然后設(shè)置比較類型StringComparison.Ordinal來實(shí)現(xiàn):
低效率的內(nèi)置字符串API:
除了上面講的順序比較外,也有一些C#的字符串的API效率比較低。比如:String.Format,String.StartsWith和String.EndsWith。以下是Unity給出的一些測試數(shù)據(jù):
可見,如果是我們自己實(shí)現(xiàn)String.StartsWith和String.EndsWith,執(zhí)行效率會高的多。實(shí)現(xiàn)方法也可以參考下圖:
正則表達(dá)式:
在字符串匹配和操作字符串方面,正則表達(dá)式是非常消耗性能的。而且,C#類庫也實(shí)現(xiàn)了正則表達(dá)式。所以,即使是調(diào)用IsMatch這樣簡單的函數(shù),都會臨時分配很多的內(nèi)存。我們在開發(fā)中,出了初始化會臨時分配內(nèi)存外,應(yīng)該不允許在其他地方臨時分配較多內(nèi)存。
如果一定要用正則表達(dá)式的話,注意不要使用靜態(tài)的Regex.Match和Regex.Replace方法。這兩個方法會動態(tài)的編譯正則表達(dá)式,但不會緩存生成的對象。
下面是使用正則表達(dá)式的一個例子:
每一次以上的代碼被執(zhí)行,它都會生成5kb的內(nèi)存垃圾。為了減少垃圾的生成,我們需要對以上代碼進(jìn)行重構(gòu):
在這個例子中,每一次調(diào)用myRegExp.Match只會產(chǎn)生320b的內(nèi)存垃圾。對于簡單的字符串匹配而言,它對內(nèi)存的消耗依舊有點(diǎn)多,但與之前的例子相比,這已經(jīng)是很大的改進(jìn)了。
因此,如果正則表達(dá)式是不變的字符串常量,那么把它們當(dāng)作第一個參數(shù)傳遞給Regex的構(gòu)造器來預(yù)編譯它們會更加有效。這些Regex對象也是可以被重用的。
XML, JSON和其他的長篇文本解析:
在loading時,解析文本通常是一項(xiàng)耗時的操作。有些情況下,解析文本所花的時間會超過loading和實(shí)例化Assets的時間。
這原因取決于我們用的文本解析器。C#內(nèi)置的XML解析器是非常靈活的,但是,它不能對一些特殊的數(shù)據(jù)布局進(jìn)行優(yōu)化。
許多第三方解析器都是基于反射構(gòu)建的。雖然在開發(fā)中使用反射是一個不錯的選擇(因?yàn)樗芎芎玫倪m應(yīng)數(shù)據(jù)布局的變化),但用反射是非常慢的。
Unity已經(jīng)引入了一個帶有內(nèi)置JSONUtility API(可參考:
如果在文本解析中遇到性能問題,可以考慮以下的解決方案:
1.在Build時進(jìn)行解析
當(dāng)我們需要解析文本時,最好避免在游戲中進(jìn)行這一步的操作。我們可以在Build的時候把文本解析成二進(jìn)制文件。以加快讀取時的速度。
2.數(shù)據(jù)分割和延遲加載
第二種情況情況是我們需要把能解析成小塊的數(shù)據(jù)分割開來。一旦分割,數(shù)據(jù)解析就可以在不同時間進(jìn)行。在理想的情況下,我們確定哪部分?jǐn)?shù)據(jù)是會用到的,然后只加載用到的那部分?jǐn)?shù)據(jù)。
3.線程
對于那些不需要用Unity API來操作的數(shù)據(jù),可以在另外的線程中來解析它們。這可以提高多核CPU的利用率,是相當(dāng)有用的。當(dāng)然,我們在寫代碼時需要注意避免死鎖。
總結(jié)
以上是生活随笔為你收集整理的unity中链接字符串和变量显示_理解Unity中的优化(六):字符串和文本的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 轮胎一般多少钱啊?
- 下一篇: 按钮旁边加一个提示_地铁站的那些“红色按