C 字串解析相關優化

2021-08-09 06:15:01 字數 3897 閱讀 2230

前兩天做了遊戲(unity專案)中新手引導配置檔案檢查的功能,配置寫在lua指令碼中,詢問專案中的前輩後,呼叫了統一的介面載入遊戲中所有lua檔案,獲取到luatable,對其中按鈕路徑進行了檢查,主要目的是防止prefab更新後未更新配置檔案,這會導致新手引導中對應的按鈕找不到。反覆除錯檢查後,自信的提交了任務,主程來驗收後表示錯漏百出,**格式沒遵守規範,迴圈中重複載入資源,反覆呼叫得到相同結果的函式……

**風格每個人習慣不一樣沒有好壞之分就忽略他了,其他通用的記下來自省,也希望能對大家有幫助。

先上優化前**

hashtable readluatableashash()

bool checksingle(string wnd, string btn)

void main()}}

}

**執行起來是完全正確的,程式老鳥和細心的朋友應該已經發現**不對了,「」只是過載了方法,不管資料結構如何優化都是需要耗費效能的,需要重複使用的資料,只獲取一次到變數中,於是做了如下修改。

void main()

string strinterwndname = objinterwndname.tostring();

string strinterbtnpath = objinterbtnpath.tostring();

if (!checksingle(strinterwndname, strinterbtnpath))}}

}

其實這個問題很基礎,偶爾會忘記,但卻是**中常用到的,用得多了對效能影響自然也就大了。

呼叫統一介面載入lua檔案的時間有些長,而且對於檢查配置這一功能來說,這樣的操作有些浪費,所以新的需求是用讀文字的形式讀取lua檔案。

小科普

所有檔案本質上都是二進位制檔案,一堆0和1,檔案本身並沒有意義,關鍵看如何解讀。

於是把lua檔案當做純文本來解析,要解決的問題主要有兩個:

1.去除備註以及文字中luatable以外的元素

2.將luatable解析出來

這其中肯定要識別關鍵字,例如

public

static hashtable readluatable(string content)

else

}if (tempstr.replace(" ", "").replace("\t", "") == "")

#endregion

#region 檢查是否為函式,忽略他

if (tempstr.contains("function"))

else

if (tempstr.contains("end"))

}if (isfunction)

#endregion

content[i] = tempstr;

}strfinal = string.join("", content);

dicmatchlength = new hashtable();

#if log_parse_time

long elapsed = system.datetime.now.ticks - currenttime;

debug.log("預處理lua檔案消耗時長 : " + elapsed);

currenttime = system.datetime.now.ticks;

#endif

table = readluatable(strfinal.replace("\\\\", "\\"), 0) as hashtable;

#if log_parse_time

elapsed = system.datetime.now.ticks - currenttime;

debug.log("解析lua檔案消耗時長 : " + elapsed);

#endif

return table;

}

我一開始的做法顯得比較笨拙,首先讀取檔案,採用了file.readalllines()來讀取檔案,這裡會把二進位制檔案逐行讀成string,對每行string查詢關鍵字,以檢測是否為注釋或函式,這些地方會影響到之後解析luatable。解析luatable需要逐字解析,所以最後我用string.join()將陣列重新變為單個string,不難察覺,生成這麼多臨時的string並不合適,這將會占用儲存空間,且效率不高。

同時有幾個小技巧,可以進一步優化**。

1.string.indexof()與string.contains()這個函式能夠達到相同效果,當string.indexof(『,』)得到的值小於0時則當前string不存在』,』。

2.content.replace();content.substring();等函式將會生成臨時string以返回結果,盡量少用。

嗯,這幾點我當然本來也沒注意,又是主程一秒點破,於是之後重構了**。

public

static hashtable readluatable2(system.io.streamreader file)

else

if (indexofcomment == 0)

bool bemptyline = true;

for (int j = nlinestartat, jmax = nlinestartat + nsubstringlength; j < jmax; j++)

}if (bemptyline)

}#endregion

#region 檢查是否為函式,忽略他

if (!isfunction)

}else

}if (isfunction)

#endregion

}#if log_parse_time

long elapsed = system.datetime.now.ticks - currenttime;

debug.log("預處理lua檔案消耗時長 : " + elapsed);

#endif

string strfinalfinal = strfinal.tostring().replace("\\\\", "\\");

dicmatchlength = new hashtable();

#if log_parse_time

currenttime = system.datetime.now.ticks;

#endif

table = readluatable(strfinalfinal, 0) as hashtable;

#if log_parse_time

elapsed = system.datetime.now.ticks - currenttime;

debug.log("解析lua檔案消耗時長 : " + elapsed);

#endif

return table;

}

前後對比了時間,後者更穩定且一直略快於前者,第一次快20ms,多執行幾次後,前者時間越來越接近後者,應該是unity內部對string的操作進行了什麼神秘的優化,但總體來說,後者策略是要優於前者的,當然也視各位的具體情況而定。

動態載入資源,無論是遊戲本身還是類似我在寫的檢查工具都經常用到。

unityeditor.assetdatabase.loadassetatpath(path);

gameobject getassets(string path)

else

}

封裝這麼乙個方法就可以在第一次檢查之後省下載入資源的時間。

好的不喜歡說自己是萌新的萌新分享結束了,有錯誤的地方大家糾正,想要討論問題也歡迎發郵件到[email protected],之前放qq號上去發現這樣qq會加了許多平時不聯絡的人,還是郵箱來得舒服,哈哈。

c語言字串相關

在c語言中,有兩個函式可以在控制台 顯示器 上輸出字串,分別是 在c語言中,有兩個函式可以讓使用者從鍵盤上輸入字串,它們分別是 但是,scanf 和 gets 是有區別的 strcat 是 string catenate 的縮寫,意思是把兩個字串拼接在一起,語法格式為 strcat arraynam...

mysql解析json字串相關問題

很多時候,我們需要在sql裡面直接解析json字串。這裡針對mysql5.7版本的分水嶺進行區分。1.對於mysql5.7以上版本 使用mysql的內建函式json extract column,key 這個函式有兩個引數,第乙個引數column代表json列的列名 第二個引數key代表json字串...

字串相關 C 字串輸出格式

近段時間在做專案時用到了字串輸出格式方面的內容,今天來整理一下,算是筆記吧,如果能幫到部分我也是很開心噠。1 大部分開發者會選用加號鍵組合字串並輸出 string str hello string name jerry string result str name 輸出結果 2 我們還可以選用格式化...