簡體   English   中英

Closure Compiler如何使用類型信息編譯為更快的JavaScript?

[英]How does Closure Compiler use type information to compile to faster JavaScript?

Google的Closure Compiler編譯為更高效的JavaScript。 我可以想象一些簡單的例子,例如Closure Compiler通過直接調用函數或用文字替換常量來減少調用堆棧。 文檔更進一步說,

“Closure Compiler可以使用有關JavaScript變量的數據類型信息來提供增強的優化和警告。”

我的理解是類型化語言有兩個好處:1)類型檢查可以在編譯期間捕獲錯誤 - 我可以看到Closure Compiler如何模擬這種行為 - 和2)程序實際執行得更快,因為它被編譯成另一種語言(比如說) Java到Java字節碼)。 使用Closure Compiler,輸出仍然是JavaScript。 如何根據類型信息進行優化?

一個示例是disambiguateProperties功能,在http://closuretools.blogspot.com/2011/01/property-by-any-other-name-part-3.html中有所描述。

正如帖子所描述的,這允許編譯器選擇較短的屬性名稱。 它還允許編譯器消除更多的死代碼。 假設您在代碼中調用x.foo() ,並且有兩種不同的類型都有foo方法:

X1.prototype.foo = function() {
  // Lots and lots of code...
};


X2.prototype.foo = function() {
  // Lots and lots of code...
};

如果編譯器不知道x是什么類型,它必須在代碼中保留兩個long foo方法,即使它們中的一個可能永遠不會被調用。 如果它知道xX1類型,那么它會將方法重命名為X1$fooX2$foo (或類似的東西)。 然后,它可以看到X2$foo永遠不會被調用,因此它會從編譯的代碼中刪除它。 這意味着下載和解析的代碼更少,因此它可以使頁面感覺加載速度更快,並且JS解釋器必須保留在內存中的功能少一個。

Closure Compiler中基於類型的“優化”本身並不是純粹的優化。 在編譯器術語中,它嚴格地暴露了其他優化的機會。

以下是我在http://closure-compiler.appspot.com/home上構建的示例

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @use_types_for_optimization true
// @formatting pretty_print
// @output_file_name default.js
// ==/ClosureCompiler==

/** @constructor */
function X(){}
X.prototype.foo = function() {alert("X")};

/** @constructor */
function Y(){}
Y.prototype.foo = function() {alert("Y")};

window.i = new X();
window.j = new Y();


/**
 * @param {!X} x
 */
window.keep = function(x) {
 x.foo();
}

如果您將* use_types_for_optimization * true切換為false ,您會注意到警報不再被內聯。 請注意,如果沒有類型信息,則無法告訴調用者keep始終為X.

從這個意義上說,類型信息有助於內聯。

希望有所幫助。

該文檔沒有說明創建執行速度更快的代碼。 編譯器的重點始終是檢查和代碼大小。 雖然它可以生成運行速度更快的代碼(通常通過刪除間接),但它也可以創建運行速度較慢的代碼,因為創建的代碼違反了JS VM的某些優化標准(創建太大的函數等)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM