Lua,ILRuntime, HybridCLR(wolong)/huatuo熱更對比分析
這兩年,各種Unity熱更新方案如雨后春筍般出來了,今天來寫篇文章來對比一下Unity各大熱更新方案的優(yōu)缺點(diǎn)。目前主流的Unity熱更新的方案有:
Lua系解決方案: 內(nèi)置一個Lua虛擬機(jī),做好UnityEngine與C#框架的Lua導(dǎo)出。典型的框架有xLua, uLua,大體都差不多。
ILRuntime解決方案: 內(nèi)置一個.net 字節(jié)碼解釋器,解釋執(zhí)行.net字節(jié)碼。
puerts解決方案: 內(nèi)置一個JavaScript/TypeScript解釋器,解釋執(zhí)行TypeScript代碼。
HybridCLR(wolong) huatuo: HybridCLR(wolong)之前的名字叫做huatuo,在Unity的il2cpp里面添加一個可以裝載.net字節(jié)碼,解釋執(zhí)行.net的字節(jié)碼的功能。
接下來我們從幾個點(diǎn)來分析比對這幾個熱更新的方案:
(1) 可熱更的代碼的范圍;
(2) 發(fā)布新版本的時,新版本的性能與老版本熱更;
(3) 熱更解釋執(zhí)行效率的對比分析;
(4) 哪種方案更符合開發(fā)者的開發(fā)習(xí)慣;
可熱更的代碼的范圍對比
Lua,方案都是項(xiàng)目種內(nèi)置Lua虛擬機(jī),它能熱更的范圍是使用Lua開發(fā)的所有腳本都可以熱更,C#開發(fā)的代碼可以通過提前的hotfix來做熱更補(bǔ)丁。雖然Lua方案看上去Lua代碼和C#代碼都可以熱更,但是其實(shí)hotfix來做c#代碼熱更的時候,需要打標(biāo)記,你無法預(yù)判哪些需要C#可能會被更新,同時hotfix經(jīng)過幾個版本迭代,以前版本有熱補(bǔ)丁,新版本沒有熱補(bǔ)丁,管理起來非常的麻煩。
ILRuntime/purets方案都是Unity內(nèi)置.net字節(jié)碼解釋器/TypeScript/JavaScript解釋器, 在熱更項(xiàng)目中編寫的代碼,都可以熱更,但是普通C#編寫的代碼無法熱更新。HybridCLR(wolong) huatuo方案: 在IL2CPP VM中內(nèi)置一個.net 字節(jié)碼解釋器,同時還會把.net里面的數(shù)據(jù)對象映射到native 的數(shù)據(jù)對象,所以huatuo的任何c#編寫的代碼都可以熱更新。
這一局, HybridCLR(wolong) huatuo完勝??梢愿氯我釩#實(shí)現(xiàn)的代碼,如果要熱更新,就把這個c#代碼所在的.dll字節(jié)碼庫裝載到il2cpp vm 就可以解釋執(zhí)行,如果不加載.dll的字節(jié)碼,就使用原來的 il2cpp的native代碼。
新版本的性能與老版本熱更
這一局也是HybridCLR(wolong) huatuo完勝,當(dāng)有新版本發(fā)送的時候,比如1.0, 我們開發(fā)了一些熱更代碼,到2.0, 發(fā)布2.0的時候,1.0的是熱更了服務(wù)器上的代碼解釋執(zhí)行, 2.0是直接代碼就可以了,但是Lua/purets/ILRuntime 2.0版本都是解釋執(zhí)行,而HybridCLR(wolong) huatuo, 1.0是加載更新的.dll 到il2cpp vm虛擬機(jī),解釋執(zhí)行IL字節(jié)碼。但是當(dāng)我們發(fā)布2.0的時候,就不用加載.dll, 那么直接使用2.0 il2cpp轉(zhuǎn)好的native代碼直接可以被機(jī)器執(zhí)行,所以其它方案都是解釋執(zhí)行,而HybridCLR(wolong) huatuo新版本是native 代碼??偨Y(jié)一下Lua/ILRuntime/puerts熱更方案,新版本都是解釋執(zhí)行熱更代碼,而HybridCLR(wolong) huatuo使用native代碼直接運(yùn)行,新版本native性能,比解釋執(zhí)行性能要好。
熱更解釋執(zhí)行效率的對比分析
上面分析了,新版本的時候,Lua/ILRuntime/puerts仍然是解釋執(zhí)行,而HybridCLR(wolong) huatuo是native code,接下來分析一下都是熱更解釋執(zhí)行效率與性能的對比,Lua/ILRuntime/puerts是在C#層內(nèi)置虛擬機(jī),所以熱更代碼的內(nèi)存,都是運(yùn)行在虛擬機(jī)域的內(nèi)存對象,如果要訪問native c#的對象,都要用函數(shù)包起來來訪問,而HybridCLR(wolong) huatuo在解釋執(zhí)行IL字節(jié)碼的時候,先把字節(jié)碼的對象內(nèi)存,映射成native內(nèi)存塊,所以熱更解釋執(zhí)行IL字節(jié)碼的同時,能直接訪問 native內(nèi)存對象。這樣就不用像其它熱更一下用函數(shù)包起來,性能達(dá)到最好。數(shù)據(jù)對象的內(nèi)存訪問已經(jīng)討論了,接下來在看解釋執(zhí)行,都是解釋二進(jìn)制字節(jié)碼,這些解釋執(zhí)行的效率基本都在一個數(shù)量級上,由于HybridCLR(wolong) huatuo可以直接訪問native 內(nèi)存對象,所以熱更部分的執(zhí)行性能上HybridCLR(wolong) huatuo要優(yōu)于其它方案
哪種方案更符合開發(fā)者的開發(fā)習(xí)慣
這局又是HybridCLR(wolong) huatuo完勝,使用HybridCLR(wolong) huatuo熱更方案的時候,你不用管哪些要熱更,哪些不用熱更新,只要按照模塊利用Unity 的ADF機(jī)制來生成不同的項(xiàng)目,并生成對應(yīng)的.dll, 底層打包的時候,都統(tǒng)一用il2cpp轉(zhuǎn)成native code, 如果新版本哪個.dll 要更新了,只要把生成的新版本的.dll放服務(wù)器上,那么就從服務(wù)器裝載進(jìn)來到il2cpp vm中,這樣就可以解釋執(zhí)行。所以HybridCLR(wolong) huatuo 和普通的Unity開發(fā)幾乎一樣。
而其它的方案,都要分成native c# 工程和熱更項(xiàng)目代碼,這樣不方便相互之間的調(diào)用,還要維護(hù)熱更代碼與框架代碼等,比較麻煩,不符合普通Unity的開發(fā)習(xí)慣。如果你有一個Unity的項(xiàng)目要支持熱更新,一定使用HybridCLR(wolong) huatuo方案能讓你少改代碼。所以開發(fā)習(xí)慣這塊,HybridCLR(wolong) huatuo優(yōu)于其它的方案。
?
通過幾個對比,以HybridCLR(wolong) huatuo為代表的基于il2cpp vm的熱更方案,將會是Unity熱更方案的主流首選。如果不出意外,未來的熱更的趨勢就是HybridCLR(wolong) huatuo這種技術(shù)原理的熱更方案。