本文翻译自 Chrome DevTools: Show native functions in JS Profile,中文版首发在我的知乎专栏 V8 源码及周边。

在 Chrome DevTools 中可以使用 profiler 查看原生函数的执行性能:

原生函数(native function)是 JavaScript 语言的一部分,这些函数有别于开发者编写的自定义函数。当我们在 profiler 中查看代码的调用栈时,这些函数是被过滤掉的。我们在 profiler 中看到的只有自己写的代码。

当我们捕获调用栈时,Chrome 并不会捕获 C++ 写的函数。不过,在 V8 引擎中很多 javascript 原生函数都是使用 javascript 语言编写的。

V8 使用 JavaScript 本身实现了 JavaScript 语言的大部分内置对象和函数。 例如,promise 功能就是通过 JavaScript 编写的。我们把这样的内置函数称为自主托管(self-hosted)。

如果我们开启 “Show native functions” 设置,Chrome 将会在 profiler 中显示这些函数。

Chrome 分析器是如何工作的

为了找到那些耗时最多的代码,Chrome 分析器每 100μs 捕获一个堆栈跟踪。

这意味着,如果一个函数只需要 50μs 的执行时间,就可能不会在分析器中显示出来!

当你分析几毫秒以上的时间时,可以准确了解应用程序在何时花费最多的时间。 但是,当你放大 profiler 面板想看更精准的时间时,信息会变得不太准确。

分析器也会不一致。 每次运行时,会产生一个稍微不同的结果。 有时可能会记录非常短的函数调用,而在其他时间再次运行这些函数调用信息可能会丢失。

通过这篇博客文章我将为大家演示如何捕获并分析原生函数的性能。当你自己运行代码时,结果可能会有所不同。

Array.join

首先,我们运行如下代码:

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”:

我们再次运行时,把 “Show native functions” 启用:

当我们把鼠标指向函数时,会看到更加详细的信息:

如上信息中,chrome devtools 展示了原生函数的行号,你可以在 Chrome code search中找到这个文件 “array.js”。行号信息可能不同,因为 V8 源码的最新版本和 Chrome 使用的 V8 版本可能不一样。

你可以看到 ArrayJoin 函数在内部调用了 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 在内部调用了 DoJoin

DoJoin 调用了 %StringBuilderJoin

%StringBuilderJoin 是使用 C++ 实现的。

稀疏数组

我们有点偏离主题,但是我认为 V8 处理稀疏数组(new Array(n))是非常有趣的。

为什么这很有用呢?

下面的代码是如何运行的?

arr = new Array(10000000)
for (var i=0; i<10000; i++){arr.push(i)
}
console.profile("arr + arr")
arr + arrconsole.profileEnd("arr + arr")复制代码

您通常不会在两个数组上执行加操作。但是由于某种原因,我最近看过的一些代码就是这样做的。

当不是用查看原生函数时,我们看到了一个匿名函数的调用。

当我们开启了查看原生函数功能时,Chrome 调用了 arraytoString 方法,然后调用了 join 方法。

Error().stack

我们来看一个不同的例子。在 JavaScript 中,您可以使用 Error().stack 获取当前正在运行的函数的堆栈跟踪(stack trace)。

当我们运行该代码时,一共做了两件事: 首先我们创建一个新的 Error 对象,然后访问它的 stack 属性。

获取堆栈跟踪的字符串描述信息时,耗费了大量的时间。

我能够通过获取一个 Error 对象来加快我正在处理的代码:只有当我需要显示堆栈跟踪时,才解析其 stack 属性。

不准确的地方

在我的文章的开头章节,我提到了非常小的时间间隔可能造成结果的不准确。为了说明这一点,我在另一台不同配置的电脑上运行了 Error().stack 的代码段。

我们看到了 FormatErrorString 函数,而在之前的分析中,这个函数并没有显示出来。

(这次的总执行时间是 ~1ms,这意味着 Chrome 需要 10 个调用堆栈的样本。上面的例子花了 ~10ms,因为我在循环中调用了 10 次 Error().stack。)

相关阅读

  • 移动 Web 滚动性能优化:Passive Event Listeners
  • 使用 D8 分析 javascript 如何被 V8 引擎优化的
  • 开启 V8 对象属性的“fast”模式

如果对 V8 引擎干兴趣,我在 4月15(星期六)晚 8 点和大家一起聊聊 V8 引擎:前端程序员应该懂点 V8 知识 - SegmentFault 讲堂。

Chrome DevTools:在 Profile 性能分析中显示原生 javascript 函数相关推荐

  1. 【chrome devtools】前端性能分析之chrome devtools的使用 前端项目内存性能优化的建议 前端浏览器崩溃卡死 前端性能分析实战

    最近有个项目,静置一段时间,chrome内存一直上涨.就像是这样: 内存会慢慢悄悄的往上涨,最终可以到达2000多M,直至浏览器崩溃卡死.很明显,这应该是内存泄漏了. 但是只知道内存泄漏,并不知道究竟 ...

  2. linux性能监控工具perf,Linux性能分析中常用的工具perf介绍

    今天小编要跟大家分享的文章是关于Linux性能分析中常用的工具perf介绍.系统级性能优化通常包括两个阶段:性能剖析(performance profiling)和代码优化.性能剖析的目标是寻找性能瓶 ...

  3. [MSSQL]也说SQL中显示星期几函数

    网上盛传着三个版本,分别来看下 版本1 http://bernardstudios.com/select-day-of-week-name-using-t-sql/ SELECT CASE (DATE ...

  4. 浏览器调试工具网页性能分析中的使用

    IE.chrome.firefox等按F12可以掉出它们自带的页面调试工具,作为测试当然不能非常精通在页面上修改样式,调试页面jsp,js,但是却可以很轻松的使用它来分析网页的性能优化项. 基础篇 现 ...

  5. 使用WebPageTest、Lighthouse和Chrome DevTools评估网站性能

    目录 一:使用WebPageTest评估网站性能 二:使用Lighthouse分析性能 1.本地npm安装Lighthouse 2.Chrome DevTools中使用 三:使用Chrome DevT ...

  6. extjs中滚动条属性_36个工作中常用的JavaScript函数片段「值得收藏」

    作者:Eno_Yao 转发链接:https://segmentfault.com/a/1190000022623676 前言 如果文章和笔记能带您一丝帮助或者启发,请不要吝啬你的赞和收藏,你的肯定是我 ...

  7. python profile 性能分析

    背景 自己写了一个小型项目, 写完发现运行一次要好几秒, 瓶颈在哪呢? 有无优化空间? 涉及到的对象比较多, 方法间的嵌套和递归调用也不少, 很难手工打印时间戳去分析耗时. 此时就需要专业工具啦. c ...

  8. matlab中显示由imread函数读取的各个通道的图像

    要显示一个由 imread 函数读取的图像的各个通道,可以使用 imshow 函数结合 imread 函数来完成.以下是一些示例代码: 显示RGB图像的各个通道: rgb_image = imread ...

  9. html中事件调用JavaScript函数时有return与没有return的区别

    2019独角兽企业重金招聘Python工程师标准>>> JAVASCRIPT在事件中调用函数时用return返回值实际上是对window.event.returnvalue进行设置. ...

最新文章

  1. uniny 物体运动到一个点停止_隐藏的几何:各类随机物体中的深层联系
  2. 服务器USB启动故障一例
  3. Nuget 启用数据库迁移的时候一定要把包含DbContext的项目设为启动项目
  4. 怎样考计算机教师资格证书,非师专生怎么考取计算机教师资格证书?
  5. spring cloud 启动bean 循环依赖问题记录
  6. Gradle - 编译报org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm的问题解决
  7. junit 生成html报告,gradle – 如何为JUnit 5测试创建HTML报告?
  8. 解决:如何卸载WPS的vba宏功能
  9. 怎么让照片里的人嘴巴动起来_动嘴app最新版(让照片说话的软件)|动嘴app安卓版下载v1.0.0-乐游网安卓下载...
  10. 花花公子发大招!一款可以“美容”的安全套,极致××体验从它出发 | 钛空舱
  11. 工作笔记(python给excel加密)
  12. Android系统文件夹结构介绍
  13. synchronized批量重偏向与批量撤销
  14. The Biggest Water Problem
  15. 【ACM-ICPC 2018 南京赛区网络预赛 E】AC Challenge
  16. husky gazebo
  17. ubuntu 录屏软件
  18. SpringBoot实现小程序微信支付统一下单
  19. 由于找不到opencv_world310d.dll,无法继续执行代码。重新安装程序可能会解决此问题。
  20. 手持两把锟斤拷,口中疾呼烫烫烫。 脚踏千朵屯屯屯,笑看万物锘锘锘。

热门文章

  1. python sanic加速_python微服务sanic 使用异步zipkin(2) - 一步步创建Sanic插件: sanic-zipin...
  2. 伪造谷歌安全类的钓鱼邮件案例
  3. mysql5.5.3下载_MySQL5.5.5M3发布-下载_MySQL
  4. linux awk 教程,AWK简单使用方法
  5. python高精度加法_14.高精度加法
  6. 两个三维图像互信息python_python – 使用numpy计算成对互信息的最佳方式
  7. jquery ajax 删除数据,JQuery ajax 保存数据,删除数据
  8. pycharm中import报错 命令行import正常
  9. 《系统集成项目管理工程师》必背100个知识点-15项目章程ITTO
  10. 笔记整理-信息系统开发基础-软件测试-模糊测试