JS特性性能缺陷及JIT的解决方案

标签: js 性能 jit | 发表时间:2013-02-06 19:10 | 作者:hyddd
出处:http://www.cnblogs.com/

        拜读了David的《 Know Your Engines: How to Make Your JavaScript Fast》,David是Mozilla的JS引擎工程师,文章主要介绍了JIT与GC原理,以及如何根据某些基本原理,优化js代码的执行效率,虽然是老文了,但对我来说仍受益匪浅。这里,我根据上文整理了本文,同时,大家也可以从侧面了解下JIT。

 

        近5年来,在主流浏览器上,Javascript的运行速度有10-100倍的提升,这要归功于Javascript新引擎JIT。但在深入了解JIT前,我们先看看Javascript的一个最重要的特性:untyped(无类型)。

 

一. 无类型:

        Javascript是个无类型的语言,这导致了 x = y +z这种表达式,可以有很多含义。比如:

        (1)y,z是数字,则+表示加法。

        (2)y,z是字符串,则+表示字符串连接。

          ……

        而JS引擎内部则使用“细粒度”的类型,比如:32-bit* integer, 64-bit* floating-point,如图:

        2

        这就要求js类型-js引擎类型,需要做“boxed/unboxed(装箱/解箱)”,在处理一次x = y + z这种计算,需要经过的步骤如下:

        (1)从内存,读取 x = y + z的操作符。

        (2)从内存,读取 y,z。

        (3)检查y,z类型,确定操作的行为。

        (4)unbox y,z。

        (5)执行 操作符 的行为(唯一有效的步骤……)。

        (6)box x。

        (7)把x写入内存。

        只有(5)是真正有效的操作,其他都是为(5)做准备/收尾的,效率之低可见。javascript的untyped特性很好用,但也为此付出了很大的性能代价。

 

二. 对象属性

function f(obj) {
return obj.a + 1;
}

        在Js里,对象属性的访问是比较慢的。至于原因,要从Javascript对象存储说起,这里借用其他文章的一个图:

        4

        如上图,访问对象属性,需要先从本地变量表找到对象,然后遍历属性,如果在本对象的属性列表里没找到,再得从prototype里面一层层的找。不能直接索引,只能遍历,这就慢的原因。

 

二. 2006版-Javascript引擎

        这版引擎在执行x = y + z时,就是执行了以上流程。它模块图如下:

        2013-02-06_170725

 

三. 2011新版-Javascript引擎

        模块图如下:

        3

        可以看到,除了老版的解析器外,新引擎增加了JIT,以及Type-specializing JIT。

 

1. JIT

        先看看JIT对untyped的优化,在JIT下,执行x = y + z流程:

        (1)从内存,读取 x = y + z的操作符。

        (2)从内存,读取 y,z。

        (3)检查y,z类型,确定操作的行为。

        (4)unbox y,z。

        (5)执行 操作符 的行为(唯一有效的步骤……)。

        (6)box x。

        (7)把x写入内存。

        其中,(1),(2) CPU帮我们搞定;(7)JIT把结果保存在寄存器里。

        但可惜不是所有情况都能使用JIT,上面看到,Front-end有3条分支,“一般的情况”可以走JIT分支,比如:number + number;string + string …,但特殊情况,比如:number + undefined就不行了,只能走旧解析器。

 

        除了针对untyped的优化,新引擎还对“对象属性”访问做了优化,解决方案叫:inline caching,俗称:IC。简单的说,就是做cache。优化流程直接看图:

        5

        这个相当于遍历cache list了,如果当list很大时,这种方案反而影响效率。下图是评测:

        7

 

2. Type-specializing JIT

        从名称上可以猜到,这个引擎是处理typed类型(声明类型)变量的。厄……但Javascript都是untype类型的……

        Type-specializing JIT的解决方案是:

        (1)先通过扫描,监测类型。

        (2)通过编译优化(当然,他的优化对象不仅仅只是“类型”,还包括对JS代码的优化,但类型优化是核心的。),生成类型变量。

        (3)再做后续计算。

 

         来看看Type-specializing JIT的执行x = y + z流程吧:

        (1)从内存,读取 x = y + z的操作符。

        (2)从内存,读取 y,z。

        (3)检查y,z类型,确定操作的行为。

        (4)unbox y,z。

        (5)执行 操作符 的行为。

        (6)box x。

        (7)把x写入内存。

        高效的优化啊……当然,这也是有代价的,代价就是:前置的扫描类型,编译优化。所以Type-specializing JIT的应用是有选择性,选择使用这个引擎的场景包括:

        (1)热点代码。

        (2)通过启发式算法估算出来的有价值的代码……

   

        另外,有2点也需要注意:

        (1)当 变量类型 发生变化时,引擎有2种处理方式:

                【1】少量变更,重编译,再执行。

                【2】大量变更……还是交给JIT执行吧。

        (2)数组,object properties,闭包变量不在优化范畴之列。

 

        本文主要整理了JIT针对Javascript某些语言特性的优化方案,至于GC,以及更多Js代码优化建议,可查阅原文。

本文链接

相关 [js 性能 jit] 推荐:

JS特性性能缺陷及JIT的解决方案

- - 博客园_首页
        拜读了David的《 Know Your Engines: How to Make Your JavaScript Fast》,David是Mozilla的JS引擎工程师,文章主要介绍了JIT与GC原理,以及如何根据某些基本原理,优化js代码的执行效率,虽然是老文了,但对我来说仍受益匪浅.

JS性能优化笔记

- - CSDN博客Web前端推荐文章
通过网上查找资料了解关于性能优化方面的内容,现简单整理,仅供大家在优化的过程中参考使用,如有什么问题请及时提出,再做出相应的补充修改. 一、 让代码简洁:一些简略的表达方式也会产生很好的优化. eg:x=x+1;在不影响功能的情况下可以简写为x++;. 二、 变量名方法名尽量在不影响语意的情况下简单.

js 中for循环和indexOf()性能对比

- Xin - 博客园-首页原创精华区
在js中提供了indexOf()函数以获取某个字符在字符串中的index,可以通过它也判断某个字符或字符串是否存在. 但同时在js中for循环也可以实现同样的效果(判断字符是否存在). var specialWord = new Array("'", "\\", "<", ">", "%", "?", "/", "+", "@", "&", "#", "$", "……", "^", "~", "!", "‘", "’", ".

Java JIT编译技术

- - 小彰
        JIT是just in time,即时编译技术. 使用该技术,能够加速java程序的执行速度. 下面,就对该技术做个简单的讲解.         首先,我们大家都知道,通常javac将程序源代码编译,转换成java字节码,JVM通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译.

Java HotSpot VM中的JIT编译

- - 并发编程网 - ifeve.com
原文地址 译者:郭蕾 校对:丁一. 本文是Java HotSpot VM and just-in-time(JIT) compilation系列的第一篇. Java HotSpot虚拟机是Oracle收购Sun时获得的,JVM和开源的OpenJDK都是以此虚拟机为基础发展的. 如同其它虚拟机,HotSpot虚拟机为字节码提供了一个运行时环境.

Facebook已将HHVM/JIT用于其开发和产品中

- - InfoQ cn
Facebook宣布,他们已经在产品中使用了 HHVM这款支持JIT编译的HipHop虚拟机,这种方案统一了开发和部署两种环境,同时为开发者带来了显著的性能收益. 因为页面加载的性能问题,Facebook决定实现一套从PHP向C++转换的工具链, 该工具链即 HipHop PHP,已于2010年开源,其中的编译器称为HPHPc.

WebView JS 交互

- - ITeye博客
WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

JS游戏引擎

- 米随随 - HTML5研究小组
If you don’t have anything better to do and want to help fellow redditors interested in JS game dev out, feel free to fork the list and modify it as you like.

來源請求.js

- 红烧鲤鱼 - Blog: timdream
很早以前就想講了,但講了大概又會被戰. 相較於英文維基百科,中文維基百科在社會和歷史條目充滿了 systemic bias. 但是那些主觀論述又不是編輯者有意加進去的,而是某種編輯者存在的社會所給予的暗示(Inception?)與集體共識,而不是原本百科全書應該有的可驗證的事實. 因為是暗示又是共識,所以有自覺的百科編輯者反而是少數;中文維基只好長成現在這個樣子了.

Js删除节点

- - JavaScript - Web前端 - ITeye博客
 方式一:传this参数调用方法:.  方式二:js方法中通过选择器获取节点:. //此处删除的是a节点 }. 方式三:通过jQuery方式获取节点:(尚未测试,有待测试. 此处a标签传this到js中,js通过this(即a节点)取parent(即p节点). (1)p.remove();可直接删除整个p节点.