本週 GWT 改良進度:加強 array 的記憶體使用方式。
GWT 會給予每個 type 一個稱為 queryId 的數字,透過檢查這個數字來模擬出 Java 的 runtime type check。舉例來說,這段程式碼「foo instanceof IFoo」會去取得 IFoo 的 queryID,假設是 42。
接著,在設定 object 的 prototype 時,會加上 map,例如:
Foo.prototype.castableTypeMap = { 42: 1 };如此一來,像「foo instanceof IFoo」會轉換成「!!foo.castableTypeMap[42]」,在這個例子會回傳 true。
一切都運作完好...... 除了 array。GWT 中模擬 array 的方式,並不是透過修改 Array.prototype,而是在 native 的 JS Array object 當中加入 field,所以「x=new Foo[10]」最終會變成像這樣:
x=makeArray({42:1});發現問題了嗎?每一次 allocation 會使用一個新的 array literal,即使它們共用相同(且 immutable)的 literal。這會浪費 JS VM 的記憶體。
這星期我增加的最佳化部份,做了兩件事:
- 所有傳給 array constructor 的 cast-map literal 會被儲存並保留在全域變數中。
- 所有 cast-map literal 如果出現兩次以上,就會被儲存並保留在全域變數中。
var x = { 42: 1 }; Foo.prototype.castableTypeMap = x; Foo2.prototype.castableTypeMap = x;視 application 規模,程式碼的量會減少 0.5~2.5%。
沒有留言:
張貼留言