热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

在上一篇文章中我们讲了如何使用GN编译V8源码,文章最后编译完成的可执行文件并不是V8,而是D8。这篇我们讲一下如何使用D8调试javascript代码。如果没有d8,可以使用node代替。新建文件 add-of-ints.js,输入以下内容:functionadd(obj){returnobj.prop+obj.pr

在上一篇文章中我们讲了如何使用 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 

运行:

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

输出结果为:

使用 D8 分析 Javascript 如何被 V8 引擎优化的

从输出结果我们可以看到 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 Math.random();
}

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

for (i = 0; i  0.5 ? a : b);

}

运行:

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

输出结果为:

使用 D8 分析 Javascript 如何被 V8 引擎优化的

使用 D8 分析 Javascript 如何被 V8 引擎优化的

可以看到这段代码能不能做内联缓存优化全看 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 8000 ? a : b);

}

运行:

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

结果为:

使用 D8 分析 Javascript 如何被 V8 引擎优化的

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


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 现在学vb6还靠得住么?语言只是工具,关键是思想。程序=算法+数据结构。除了汇编,其他语言都靠不住。随着时代的进步,很多语言跟不上开发的要求。从面向过程到面向对象,与其说是思想的进步,不如说是为了适应高速开发。除了底层汇编语言,还有那些能适应高速开发的语言。每种语言都是很有趣的。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
author-avatar
DarkBaron_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有