美文网首页
Nodejs V8 property fast lookup

Nodejs V8 property fast lookup

作者: 泡沫与周期_白羊Jerry | 来源:发表于2016-08-08 09:59 被阅读101次

前言

之所以会研究这个东西,是我在网上找了一下各个语言的执行效率比较。好吧,我承认这是个无聊的东西,不过看看总是无妨,然而我惊讶的发现,有些测试声称Java,C,Nodejs是处在同一个效率级别参见链接。这个让我很是惊讶,因为在我的理解中,像nodejs这种解释语言,每一个对象应该都是一个key-value字典结构,那么每一个属性查找的速度就会被C这种编译语言甩开一条街。
那么,nodejs的属性查找是怎么实现的?

我有很多定义说的不太准确的,大家理解意思就行。。别揪着一两个名词不放,求高抬贵手。

property lookup

property lookup,就是指找到程序中某一个对象的属性的具体内存位置以完成读写,根据我的理解,根据是否支持动态属性,编程语言的property lookup一般会有两个方案。

  • 静态属性语言
    这种语言基本都是编译语言,比如C,C++,Java。编译语言其实是不存在property lookup这个事的,或者说,他的property lookup已经在编译阶段完成了,例如下面的code:

    a.b = 24
    

    在编译后会直接变成对内存位置的写入操作,根本不需要lookup

    set pos[offset] 24         
    // 原谅我汇编稀烂,明白意思就行
    
  • 动态属性语言
    动态属性语言指的是对象的属性是可以随时动态存取的,动态属性带来了极大的灵活性,但同时也对效率带来了较大影响。
    通常动态类型语言的对象模型就是一个字典,每一次property lookup,都需要一个字典的查询过程,那么就包含了hash值的计算,然后key的字符串比较,成功后才能返回属性对应值,比如同样的一个命令:

    a['b'] = 24       //支持以字符串来动态更新属性
    

    往往会变成以下过程:

    hash_code = hash('b')
    if(a.dict[hash_code] == null) return null
    if(a.dict[hash_code].key == 'b') return a.dict[hash_code].value
    hash_code = rehash(hash_code)...      
    

    不用想也知道,每一次property lookup都这么麻烦,执行效率必然会比第一种语言低很多了。
    那么nodejs的对象模型有什么不同之处,可以弥补这条鸿沟?

V8所做的优化

这里我们拎出nodejs的执行引擎中效率最好的佼佼者--- V8引擎,看看它的特别之处。在V8的官方文档中给出了说明。V8采取了一种类似编译语言的机制:hidden class.
V8会给每一个创建的对象都创建一个hidden class,比如下面这段代码:

    funciton Person(x, y){
            this.x = x;
        this.y = y;
    }

V8会创建出三个hidden_class分别对应于 Person{}, Person {x: }, Person {x: y:},具体过程可以参见官方说明。
那么这三个hidden_class有啥作用?这个必须跟V8的Inline Cache结合起来才行。

inline cache

V8解释完js脚本后生成的不是中间语言,而是直接的机器语言。而且v8使用了inline cache技术。
inline cache具体是什么?简单的说,就是试图通过观察程序执行过程,动态的去调整代码以提高效率。
一个简单的例子

    x.a = 25

在通常的动态类型语言中会翻译成一个字典查找,不过在V8的第一次执行中,它会找到x对应的hidden_class,然后找到a在x实例中的偏移。而在以后的执行中,它会将这段代码优化成以下形式:

if(x.hidden_class == "supposed hidden class"){
    x[offset_a_in_hidden_class] = 25
}else{
    //dictionary lookup "a"
    ...
}

与其每次都去做一个基于属性的字典查询,不如试着根据上次执行的结果,猜测下,如果还是相同的class,那就可以复用执行时已经得到的offset结果。虽然JavaScript是一个动态类型语言,但是大部分时候我们的代码并没有用到这么多动态特性,因此本来一个字典操作变成了一个直接的地址比较。从而达到了静态类型语言的执行速度。
正因为这个特点,写nodejs程序时有一些可以遵循的规则,用以加快执行效率,参见链接

相关文章

  • Nodejs V8 property fast lookup

    前言 之所以会研究这个东西,是我在网上找了一下各个语言的执行效率比较。好吧,我承认这是个无聊的东西,不过看看总是无...

  • 初识NodeJS

    定义 NodeJS is a JavaScript runtime built on Chrome's V8 No...

  • Node.js基础入门

    NodeJs介绍 NodeJs是构建在V8引擎上的 JavaScript Runtime Node.js use...

  • NodeJS(一):初识 NodeJS

    1 NodeJS 是什么 NodeJS 是 javascript 的一种运行环境,是对 Google V8 引擎进...

  • [mark] nodeJS 入门

    认识 v8 引擎 深入理解nodeJS单线程 浅析NodeJS单线程模型 nodejs 初步认知 存在一个主线程,...

  • 专属博客,你值得拥有(Windows 版本)

    一、前提: 二、准备条件 NodeJs Nodejs框架是基于V8的引擎,是目前速度最快的Javascri...

  • Nodejs是什么

    不是一门语言 nodejs 是基于Chrome V8 的JavaScript运行环境nodejs 是事件驱动、非阻...

  • nodejs01

    nodejs介绍 nodejs是基于chrome V8浏览器的运行环境 没有界面操作,只是ECMAscript 没...

  • NodeJS V8引擎/基础API

    NodeJS 回顾(一) 什么是NodeJs?Node.js是一个基于V8 JavaScript引擎的JavaSc...

  • 构建良好结构的Express应用

    首先Express是什么?了解Nodejs的同学应该都很知道,这是一个基于Nodejs的Web框架。 Fast, ...

网友评论

      本文标题:Nodejs V8 property fast lookup

      本文链接:https://www.haomeiwen.com/subject/uqxrsttx.html