博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 D8 分析 javascript 如何被 V8 引擎优化的
阅读量:4614 次
发布时间:2019-06-09

本文共 2617 字,大约阅读时间需要 8 分钟。

在上一篇文章中我们讲了,文章最后编译完成的可执行文件并不是 V8,而是 D8。这篇我们讲一下如何使用 D8 调试 javascript 代码。

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

新建文件 ,输入以下内容:

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 是  的缩写,内联缓存是一种很常见的优化技术,这段简短的代码被 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 优化的,之前写过  中道:

永远不可能被优化的有:

  • Functions that contain a debugger statement

  • Functions that call literally eval()

  • Functions that contain a with statement

这个也是之前的文章,是以 Crankshaft 引擎为标准得出的结论。而 V8 已经开发了新的优化引擎——。

我们再创建另一个文件 add-of-mixed.js,输入:

// flag: --trace-opt-verbosefunction 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 引擎如何去优化。

新建文件 ,输入:

// flags: --trace-opt --trace-deoptfunction 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 引擎内部使用  来表示 Object,关于 Hidden Classes 的文章已经很多了,我就不累述了。

运行 d8 --help 可以查看所有的 d8 命令行参数。如果使用 node,直接运行 node --help 输出的是 node 的命令行参数,如果想查看 V8 的,需要使用 node --v8-options

后面章节会介绍 V8 的 GC(命令行参数 --trace-gc)以及最有意思的 --allow-natives-syntax

推荐阅读一下 V8 的  源码,这是一个 C++ 的头文件,里面几乎没有任何代码逻辑,定义了所有 javascript 代码不能被 V8 引擎优化的原因,比如:

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

后面章节介绍的 --allow-natives-syntax 相关 C++ 头文件是 ,通过 --allow-natives-syntax 参数可以在 javascript 中使用 V8 的运行时函数。我们在之前的文章中已经使用过了,例如 HasFastProperties

转载于:https://www.cnblogs.com/tianshifu/p/6379765.html

你可能感兴趣的文章
esp32-智能语音-cli(调试交互命令)
查看>>
netty与MQ使用心得
查看>>
关于dl dt dd 文字过长换行在移动端显示对齐的探讨总结
查看>>
swoolefy PHP的异步、并行、高性能网络通信引擎内置了Http/WebSocket服务器端/客户端...
查看>>
Python学习笔记
查看>>
unshift()与shift()
查看>>
使用 NPOI 、aspose实现execl模板公式计算
查看>>
行为型模式:中介者模式
查看>>
How to Notify Command to evaluate in mvvmlight
查看>>
33. Search in Rotated Sorted Array
查看>>
461. Hamming Distance
查看>>
Python垃圾回收机制详解
查看>>
jquery 编程的最佳实践
查看>>
MeetMe
查看>>
IP报文格式及各字段意义
查看>>
(转载)rabbitmq与springboot的安装与集成
查看>>
C2. Power Transmission (Hard Edition)(线段相交)
查看>>
STM32F0使用LL库实现SHT70通讯
查看>>
Atitit. Xss 漏洞的原理and应用xss木马
查看>>
MySQL源码 数据结构array
查看>>