摘要:當(dāng)我們在中查看代碼的調(diào)用棧時,這些函數(shù)是被過濾掉的。當(dāng)我們捕獲調(diào)用棧時,并不會捕獲寫的函數(shù)。不過,在引擎中很多原生函數(shù)都是使用語言編寫的。如果我們開啟設(shè)置,將會在中顯示這些函數(shù)。分析器也會不一致。
本文翻譯自 Chrome DevTools: Show native functions in JS Profile,中文版首發(fā)在我的知乎專欄 V8 源碼及周邊。
在 Chrome DevTools 中可以使用 profiler 查看原生函數(shù)的執(zhí)行性能:
原生函數(shù)(native function)是 JavaScript 語言的一部分,這些函數(shù)有別于開發(fā)者編寫的自定義函數(shù)。當(dāng)我們在 profiler 中查看代碼的調(diào)用棧時,這些函數(shù)是被過濾掉的。我們在 profiler 中看到的只有自己寫的代碼。
當(dāng)我們捕獲調(diào)用棧時,Chrome 并不會捕獲 C++ 寫的函數(shù)。不過,在 V8 引擎中很多 javascript 原生函數(shù)都是使用 javascript 語言編寫的。
V8 使用 JavaScript 本身實(shí)現(xiàn)了 JavaScript 語言的大部分內(nèi)置對象和函數(shù)。 例如,promise 功能就是通過 JavaScript 編寫的。我們把這樣的內(nèi)置函數(shù)稱為自主托管(self-hosted)。
如果我們開啟 “Show native functions” 設(shè)置,Chrome 將會在 profiler 中顯示這些函數(shù)。
Chrome 分析器是如何工作的為了找到那些耗時最多的代碼,Chrome 分析器每 100μs 捕獲一個堆棧跟蹤。
這意味著,如果一個函數(shù)只需要 50μs 的執(zhí)行時間,就可能不會在分析器中顯示出來!
當(dāng)你分析幾毫秒以上的時間時,可以準(zhǔn)確了解應(yīng)用程序在何時花費(fèi)最多的時間。 但是,當(dāng)你放大 profiler 面板想看更精準(zhǔn)的時間時,信息會變得不太準(zhǔn)確。
分析器也會不一致。 每次運(yùn)行時,會產(chǎn)生一個稍微不同的結(jié)果。 有時可能會記錄非常短的函數(shù)調(diào)用,而在其他時間再次運(yùn)行這些函數(shù)調(diào)用信息可能會丟失。
通過這篇博客文章我將為大家演示如何捕獲并分析原生函數(shù)的性能。當(dāng)你自己運(yùn)行代碼時,結(jié)果可能會有所不同。
Array.join首先,我們運(yùn)行如下代碼:
var arr = [] for (var i=0; i<1000; i++){ arr.push(i) } console.profile("Array.join") arr.join(",") console.profileEnd("Array.join")
選擇 profiler 的 “Chart” 視圖:
第一次分析時,我們不選中 “Show native functions”:
我們再次運(yùn)行時,把 “Show native functions” 啟用:
當(dāng)我們把鼠標(biāo)指向函數(shù)時,會看到更加詳細(xì)的信息:
如上信息中,chrome devtools 展示了原生函數(shù)的行號,你可以在 Chrome code search中找到這個文件 “array.js”。行號信息可能不同,因?yàn)?V8 源碼的最新版本和 Chrome 使用的 V8 版本可能不一樣。
你可以看到 ArrayJoin 函數(shù)在內(nèi)部調(diào)用了 InnerArrayJoin:
function ArrayJoin(separator) { CHECK_OBJECT_COERCIBLE(this, "Array.prototype.join"); var array = TO_OBJECT(this); var length = TO_LENGTH(array.length); return InnerArrayJoin(separator, array, length); }
InnerArrayJoin 在內(nèi)部調(diào)用了 DoJoin。
DoJoin 調(diào)用了 %StringBuilderJoin。
%StringBuilderJoin 是使用 C++ 實(shí)現(xiàn)的。
稀疏數(shù)組我們有點(diǎn)偏離主題,但是我認(rèn)為 V8 處理稀疏數(shù)組(new Array(n))是非常有趣的。
為什么這很有用呢?下面的代碼是如何運(yùn)行的?
arr = new Array(10000000) for (var i=0; i<10000; i++){ arr.push(i) } console.profile("arr + arr") arr + arr console.profileEnd("arr + arr")
您通常不會在兩個數(shù)組上執(zhí)行加操作。但是由于某種原因,我最近看過的一些代碼就是這樣做的。
當(dāng)不是用查看原生函數(shù)時,我們看到了一個匿名函數(shù)的調(diào)用。
當(dāng)我們開啟了查看原生函數(shù)功能時,Chrome 調(diào)用了 array 的 toString 方法,然后調(diào)用了 join 方法。
Error().stack我們來看一個不同的例子。在 JavaScript 中,您可以使用 Error().stack 獲取當(dāng)前正在運(yùn)行的函數(shù)的堆棧跟蹤(stack trace)。
當(dāng)我們運(yùn)行該代碼時,一共做了兩件事: 首先我們創(chuàng)建一個新的 Error 對象,然后訪問它的 stack 屬性。
獲取堆棧跟蹤的字符串描述信息時,耗費(fèi)了大量的時間。
我能夠通過獲取一個 Error 對象來加快我正在處理的代碼:只有當(dāng)我需要顯示堆棧跟蹤時,才解析其 stack 屬性。
不準(zhǔn)確的地方在我的文章的開頭章節(jié),我提到了非常小的時間間隔可能造成結(jié)果的不準(zhǔn)確。為了說明這一點(diǎn),我在另一臺不同配置的電腦上運(yùn)行了 Error().stack 的代碼段。
我們看到了 FormatErrorString 函數(shù),而在之前的分析中,這個函數(shù)并沒有顯示出來。
(這次的總執(zhí)行時間是 ~1ms,這意味著 Chrome 需要 10 個調(diào)用堆棧的樣本。上面的例子花了 ~10ms,因?yàn)槲以谘h(huán)中調(diào)用了 10 次 Error().stack。)
相關(guān)閱讀移動 Web 滾動性能優(yōu)化:Passive Event Listeners
使用 D8 分析 javascript 如何被 V8 引擎優(yōu)化的
開啟 V8 對象屬性的“fast”模式
這幾天 SF 增加了新的板塊——直播。我也收到了官方的邀請。4月15(星期六)晚8點(diǎn)和大家一起聊聊 V8 引擎:前端程序員應(yīng)該懂點(diǎn) V8 知識 - SegmentFault 講堂。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/82237.html
摘要:實(shí)現(xiàn)不定期更新技巧前端掘金技巧,偶爾更新。統(tǒng)一播放效果實(shí)現(xiàn)打字效果動畫前端掘金前端開源項(xiàng)目周報前端掘金由出品的前端開源項(xiàng)目周報第四期來啦。 Web 推送技術(shù) - 掘金騰訊云技術(shù)社區(qū)-掘金主頁持續(xù)為大家呈現(xiàn)云計(jì)算技術(shù)文章,歡迎大家關(guān)注! 作者:villainthr 摘自 前端小吉米 伴隨著今年 Google I/O 大會的召開,一個很火的概念--Progressive Web Apps ...
摘要:我打算把一些上使用的高級技巧寫成你不知道的這一系列的博文,希望大家一起學(xué)習(xí)學(xué)習(xí)。在代碼中使用的最簡單的用法就是寫個在控制臺打印一行消息。跟的區(qū)別在于會對輸出的對象進(jìn)行展開。用于顯示一組的控制臺輸出,要搭配來使用。 Web前端開發(fā)過程中必然會用到Chrome瀏覽器自帶的開發(fā)者工具Chrome DevTools,使用它作為Web前端開發(fā)性能調(diào)試的必備工具。就連隔壁的產(chǎn)品小哥都知道打開F12...
摘要:對于每個前端程序員來講都有一個終極理想,那就是搞懂引擎是如何工作的。性能經(jīng)過了兩次飛躍第次飛躍是年發(fā)布,第次則是年的。從去年底開始連載源碼分析,記錄一下自己學(xué)習(xí)源碼的點(diǎn)點(diǎn)滴滴。月星期六晚點(diǎn)和大家一起聊聊引擎前端程序員應(yīng)該懂點(diǎn)知識講堂。 對于每個前端程序員來講都有一個終極理想,那就是搞懂 javascript 引擎是如何工作的。 從我的網(wǎng)絡(luò) ID(justjavac)可以看出來,當(dāng)我開始...
摘要:是一個網(wǎng)頁版的小工具,可以用全新的方式展示性能分析的結(jié)果,幫助開發(fā)者洞悉函數(shù)調(diào)用關(guān)系,優(yōu)化應(yīng)用性能。研究表明這個數(shù)字正對應(yīng)于的值。因此知道了路徑編號,便可以知道那些函數(shù)處在激活狀態(tài)。在中用藍(lán)色表示。 OneProfile 是一個網(wǎng)頁版的小工具,可以用全新的方式展示 JavaScript 性能分析的結(jié)果,幫助開發(fā)者洞悉函數(shù)調(diào)用關(guān)系,優(yōu)化應(yīng)用性能。 點(diǎn)擊打開 OneProfile...
1、Chrome控制臺小技巧 打開和關(guān)閉抽屜式選項(xiàng)卡:按Esc鍵可打開和關(guān)閉 DevTools 的 Drawer(抽屜式選項(xiàng)卡) 在Drawer(抽屜式選項(xiàng)卡)中,你可以在 Console 控制臺中執(zhí)行命令,查看動畫檢查器(Animations),配置網(wǎng)絡(luò)條件(network conditions)和渲染(rendering)設(shè)置,搜索(search)字符串和文件等 showImg(https...
閱讀 1076·2021-11-22 14:56
閱讀 1520·2019-08-30 15:55
閱讀 3359·2019-08-30 15:45
閱讀 1655·2019-08-30 13:03
閱讀 2868·2019-08-29 18:47
閱讀 3334·2019-08-29 11:09
閱讀 2641·2019-08-26 18:36
閱讀 2615·2019-08-26 13:55