国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用 D8 分析 javascript 如何被 V8 引擎優化的

Airmusic / 2863人閱讀

摘要:負責找出經常被調用的代碼,做內聯緩存優化,后面的信息進一步說明了這個情況。我們再使用參數看看引擎如何去優化。如果使用,直接運行輸出的是的命令行參數,如果想查看的,需要使用。后面章節會介紹的命令行參數以及最有意思的。

在上一篇文章中我們講了如何使用 GN 編譯 V8 源碼,文章最后編譯完成的可執行文件并不是 V8,而是 D8。這篇我們講一下如何使用 D8 調試 javascript 代碼。

如果沒有 d8,可以使用 node 代替。

新建文件 add-of-ints.js,輸入以下內容:

function add(obj) {
    return obj.prop + obj.prop;
}

const length = 1000 * 1000;

const o = { prop: 1 };

for (let i = 0; i < length; i++) {
    add(o);

}

運行:

d8 --trace-opt-verbose add-of-ints.js
或
node --trace-opt-verbose add-of-ints.js

輸出結果為:

從輸出結果我們可以看到 add 函數被編譯器優化了,并且解釋了優化的原因。ICs 是 inline caches 的縮寫,內聯緩存是一種很常見的優化技術,這段簡短的代碼被 V8 引擎優化了兩次,但是原因卻不同。

第一次優化的原因是 small function,add 函數是小函數,為了減小函數調用的開銷,V8 引擎對 add 做了優化。

第二次的原因是 hot and stable,我在知乎另一個問題中曾說過,V8 有兩個編譯器,一個通用編譯器,負責將 javascript 代碼編譯為機器碼,另一個是優化編譯器。從上面的輸出可以看出 V8 使用的優化編譯器引擎是 Crankshaft。Crankshaft 負責找出經常被調用的代碼,做內聯緩存優化,后面的信息進一步說明了這個情況:ICs with typeinfo: 7/7 (100%), generic ICs: 0/7 (0%)。

在此再糾正之前的 2 個問題。

一個是 V8 沒有解釋器,只有編譯器,代碼是直接編譯成機器嗎執行的,這是之前的 V8,而網絡上關于 V8 的文章也大多比較老舊。這幾天為了閱讀 V8 源碼查看了網上很多關于 V8 的論文和文章,發現 V8 已經引進了解釋器。因為 V8 不僅僅可以優化代碼,還可以去優化(deopt),引入解釋器可以省去一些代碼的重編譯時間,另一個原因是解釋器不僅僅可以解釋 javascript 代碼,還可以解釋 asm 或者其他二進制中間碼。

另一個錯誤就是關于 V8 優化的,之前寫過 JavaScript 函數式編程存在性能問題么? 中道:

永遠不可能被優化的有:

Functions that contain a debugger statement

Functions that call literally eval()

Functions that contain a with statement

這個也是之前的文章,是以 Crankshaft 引擎為標準得出的結論。而 V8 已經開發了新的優化引擎——TurboFan。

我們再創建另一個文件 add-of-mixed.js,輸入:

// flag: --trace-opt-verbose

function add(obj) {
    return obj.prop + obj.prop;
}

var length = 1000 * 1000;

var objs = new Array(length);

var i = 0;

for (i = 0; i < length; i++) {
    objs[i] = Math.random();
}

var a = { prop: "a" };
var b = { prop: 1 };

for (i = 0; i < length; i++) {
    add(objs[i] > 0.5 ? a : b);

}

運行:

d8 --trace-opt-verbose add-of-mixed.js
或
node --trace-opt-verbose add-of-mixed.js

輸出結果為:

可以看到這段代碼能不能做內聯緩存優化全看 RP(人品) 了。

我們再使用 --trace-opt --trace-deopt 參數看看 V8 引擎如何去優化

新建文件 add-of-mixed-dep.js,輸入:

// flags: --trace-opt --trace-deopt

function add(obj) {
    return obj.prop + obj.prop;
}

var length = 10000;
var i = 0;
var a = { prop: "a" };
var b = { prop: 1 };

for (i = 0; i < length; i++) {
    add(i !== 8000 ? a : b);

}

運行:

d8 --trace-opt --trace-deopt add-of-mixed-dep.js
或
node --trace-opt --trace-deopt add-of-mixed-dep.js

結果為:

V8 引擎內部使用 Hidden Classes 來表示 Object,關于 Hidden Classes 的文章已經很多了,我就不累述了。

運行 d8 --help 可以查看所有的 d8 命令行參數。如果使用 node,直接運行 node --help 輸出的是 node 的命令行參數,如果想查看 V8 的,需要使用 node --v8-options

后面章節會介紹 V8 的 GC(命令行參數 --trace-gc)以及最有意思的 --allow-natives-syntax

推薦閱讀一下 V8 的 bailout-reason.h 源碼,這是一個 C++ 的頭文件,里面幾乎沒有任何代碼邏輯,定義了所有 javascript 代碼不能被 V8 引擎優化的原因,比如:

"Array index constant value too big"
"eval"
"ForOfStatement"
"Too many parameters"
"WithStatement"
……

后面章節介紹的 --allow-natives-syntax 相關 C++ 頭文件是 runtime.h,通過 --allow-natives-syntax 參數可以在 javascript 中使用 V8 的運行時函數。我們在之前的文章中已經使用過了,例如 HasFastProperties

參考文章:

V8 - A Tale of Two Compilers

Performance Tips for JavaScript in V8

Ignition: V8 Interpreter

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81446.html

相關文章

  • V8引擎深入研究目錄貼

    摘要:對于每個前端程序員來講都有一個終極理想,那就是搞懂引擎是如何工作的。性能經過了兩次飛躍第次飛躍是年發布,第次則是年的。從去年底開始連載源碼分析,記錄一下自己學習源碼的點點滴滴。月星期六晚點和大家一起聊聊引擎前端程序員應該懂點知識講堂。 對于每個前端程序員來講都有一個終極理想,那就是搞懂 javascript 引擎是如何工作的。 從我的網絡 ID(justjavac)可以看出來,當我開始...

    blastz 評論0 收藏0
  • JavaScriptV8元素種類及性能優化

    摘要:常規元素,不能表示為或雙精度的值。元素種類可從過渡轉變為。這是一個簡化的可視化,僅顯示最常見的元素種類只能通過格子向下過渡。目前有種不同的元素種類,每種元素都有自己的一組可能的優化。再次重申更具體的元素種類可以進行更細粒度的優化。 原文:Elements kinds in V8 JavaScript 對象可以具有與它們相關聯的任意屬性。對象屬性的名稱可以包含任何字符。JavaScrip...

    UsherChen 評論0 收藏0
  • 如何開始學習 V8

    摘要:如果不行的話,不用擔心,當你審查錯誤時會學習到知識的。但是任何人不得不從某處開始,也許你堅持,會在未來看到來自你的變更記錄。 本文轉載自:眾成翻譯譯者:yu-wj鏈接:http://www.zcfy.cc/article/3963原文:https://medium.com/dailyjs/how-do-i-get-started-with-v8-development-17e976eb...

    googollee 評論0 收藏0
  • ES6 解構賦值前每次都創建一個對象嗎?會加重 GC 負擔嗎?

    摘要:運行其中的可以查看引擎生成的字節碼。當我們使用解構賦值后我們可以看到,代碼明顯增加了很多,創建了一個對象。擴展閱讀理解的字節碼譯使用參數查看內存由于這個內存占用很小,因此我們加一個循環。 本文來源于知乎上的一個提問。 為了程序的易讀性,我們會使用 ES6 的解構賦值: function f({a,b}){} f({a:1,b:2}); 這個例子的函數調用中,會真的產生一個對象嗎?如果會...

    hightopo 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<