從ES2015發展以來,JavaScript支援了寫入與存取原始二元緩衝區ArrayBuffers,而ArrayBuffers無法直接被存取,程式必須要透過TypedArray或是DataView這兩種Array Buffer View物件,來使用記憶體中的資料。官方提到,過去DataView在V8中的最佳化程度遠低於TypedArrays,導致圖形密集的工作負載,或是解碼和編碼二元資料的處理效能低落。

而會有這樣的差異,造因於過去的技術選擇,官方提到,當初Asm.js選擇支援TypedArrays而不是DataViews,因此也讓引擎專注於提升TypedArrays的性能。這樣的效能差異,也驅使Google Maps等團隊的JavaScript開發人員開始避免使用DataView,轉而選擇依賴TypedArrays,雖然代價是程式碼更加複雜,但是為了效能也無可厚非。

早在5年前就有相關的錯誤報告,要求V8團隊提升DataView的性能,而終於在最近DataViews獲得改善,效能表現提升到了標準之上。提升DataView效能的第一步,就是將原本用C++實作的DataView移植到CodeStubAssembler(CSA)上,由於過去V8中DataView方法實作為內建的C++ Runtime函式,也就是說每次呼叫都需要從JavaScript翻譯至C++,再將結果由C++翻譯回JavaScript,這樣的往返成本非常高昂。

CSA是一種可移植的組合語言,可以在TurboFan機器等級的中介表現層(Intermediate Representation,IR)中撰寫程式碼,進行對V8的JavaScript標準函式庫進行最佳化等工作。使用CSA重寫DataView部分的程式碼,就能夠完全繞過C++呼叫,藉由TurboFan後端生成高效率的機器執行碼。重新改寫的DataView讓效能提高3倍。

提升DataViews效能的下一步,開發團隊對TurboFan進行兩階段最佳化。TurboFan是最佳化編譯器,能對JavaScript熱程式碼進行編譯,產生高度最佳化的機器執行碼,而該執行碼執行效率比位元組碼還要好。他們實現了TurboFan內聯,擺脫成本昂貴的函式呼叫,速度提升是C++實作的8倍。

由於在TurboFan中撰寫程式碼的目的,便是要對常見的熱案例進行最佳化,最佳化TurboFan的第二階段,便是透過刪除特殊錯誤情況的複雜處理,並在必要的時候,從底層實作解決這些問題。官方表示,這樣的方式將能減少產生的程式碼約達35%,並獲得明顯的加速。經過TurboFan兩階段了最佳化後,DataView的執行效率已經是原本的16倍。

現在JavaScript解碼以二元編碼的資料時,會經常地使用DataView,官方使用熱門JavaScript 3D函式庫Three.js進行測試,測量載入3D格式FBX檔案,整體執行時間下降了80%約80毫秒。官方表示,現在DataView實作與TypedArrays的性能相當,他們拉齊了之間的效能差異,讓DataView再次成為V8引擎中的實用選擇。

熱門新聞

Advertisement