Skip to content

第 65 题: a.b.c.d 和 a['b']['c']['d'],哪个性能更高? #111

Open
@zeroone001

Description

@zeroone001

Activity

wingmeng

wingmeng commented on Apr 29, 2019

@wingmeng

应该是 a.b.c.da['b']['c']['d'] 性能高点,后者还要考虑 [ ] 中是变量的情况,再者,从两种形式的结构来看,显然编译器解析前者要比后者容易些,自然也就快一点。
下图是两者的 AST 对比:
image

susiwen8

susiwen8 commented on Apr 29, 2019

@susiwen8

https://jsperf.com/dot-notation-vs-square-bracket-notation
实验证明dot notation更快,但深层原理不是太明白

The results seem to be about the same. What causes slowdows is when the contents of the bracket are a variable - at that point the compiler can no longer say to itself "Oh, ['foo'] is the same as .foo.. continuing on!".

LiuMengzhou

LiuMengzhou commented on Apr 29, 2019

@LiuMengzhou

看了楼顶的链接,知道了AST,还是很开心的。
菜🐔只会这么测试了。感觉[]是常量,性能差别很小。dot稍快
image

LiuMengzhou

LiuMengzhou commented on Apr 29, 2019

@LiuMengzhou
function compare(times) {
  let a = { key: {} };
  let temp = a;
  for (let i = 0; i < times; i++) {
    let tmp = temp['key'];
    tmp['key'] = {};
    temp = tmp;
  }
  temp['key']['key'] = 'surprise';

  let d0 = new Date();
  let i = a;
  while (i['key'] !== 'surprise') {
    i = i['key'];
  }
  console.log('[] time', new Date() - d0);

  let d1 = new Date();
  let ii = a;
  while (ii.key !== 'surprise') {
    ii = ii.key;
  }
  console.log('. time', new Date() - d1);
}
Zephylaci

Zephylaci commented on May 6, 2019

@Zephylaci

看到上面的模拟结果结果...
感觉不是很贴近实际的题目...
于是自己也写了一个...

var list = ['a', 'b', 'c', 'd'];
/*
//这一节为了验证对象复杂度对其的影响..
//实际上由于Object是类似hash表的结构
//所以实际上注释或者放开对这道题的结论并不影响,只是最后的总耗时线性增加而已
[...Array(100).keys()].forEach(num=>{
    list.push(num);
})
*/
var testObj = {};

list.forEach(key => {
    testObj[key] = {};
    list.forEach(key1 => {
        testObj[key][key1] = {};
        list.forEach(key2 => {
            testObj[key][key1][key2] = {};
            list.forEach(key3 => {
                testObj[key][key1][key2][key3] = Math.floor(Math.random() * 10);
            })
        })
    })
})

function testTypeA(num){
    console.time(`a.b.c.d :${num}`);
    for(var i =0;i<num;i++){
        var value = testObj.a.b.c.d;
    }
    console.timeEnd(`a.b.c.d :${num}`);
}

function testTypeB(num){
    console.time(`['a']['b']['c']['d'] :${num}`);
    for(var i =0;i<num;i++){
        var value = testObj['a']['b']['c']['d'];
    }
    console.timeEnd(`['a']['b']['c']['d'] :${num}`);
}
//测试组,每组测5次
var testList = ['10000000','15000000','20000000','30000000']
testList.forEach(num=>{
    [...Array(5).keys()].forEach(()=>{
        testTypeA(num);
        testTypeB(num);
    })
})

发现如果每组测试运行多次的话,与其说性能差距小到可以忽略不记...
不如说这个差距可以算在误差范围内..
有的时候['a']['b']['c']['d']还会快一些,所以说它性能差可能从模拟的角度有些站不住脚
不知道底层是否有对路径的缓存..
如果想验证这一点的话应该考虑是否是查找的同一个对象对这个的影响..
附上我跑的结果

截图.png

songguoguo927

songguoguo927 commented on Aug 19, 2019

@songguoguo927

var obj = {
a:{
b:{
c:{
d:1
}
}
}
}
console.time()
console.log(obj.a.b.c.d)
console.timeEnd() //default:0.763ms 0.684
// console.time()
// console.log(obj["a"]["b"]["c"]["d"])
// console.timeEnd() //default:1.100ms 0.964ms

// 结果:虽然时间都会变动,在但总体感觉使用点访问的时间要少于以[]访问。

yayxs

yayxs commented on Apr 26, 2020

@yayxs
  • 对于常见编译型语言(例如:Java)来说,编译步骤分为:词法分析->语法分析->语义检查->代码优化和字节码生成。

  • 对于解释型语言(例如 JavaScript)来说,通过词法分析 -> 语法分析 -> 语法树,就可以开始解释执行了。

    • 词法分析是将字符流(char stream)转换为记号流(token stream)
    • 语法分析成 AST (Abstract Syntax Tree)
    • 预编译,当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理!并且是先预声明变量,再预定义函数!
    • 解释执行,在执行过程中,JavaScript 引擎是严格按着作用域机制(scope)来执行的,并且 JavaScript 的变量和函数作用域是在定义时决定的,而不是执行时决定的。JavaScript 中的变量作用域在函数体内有效,无块作用域;

参考阅读

soraly

soraly commented on Jun 24, 2020

@soraly

a.b.c.d 和 a['b']['c']['d'],哪个性能更高?

a.b.c.d 比 a['b']['c']['d'] 性能高点,因为[ ]里面有可能是字符串,有可能是变量,至少多一次判断,而a.b.c.d是直接取用该字符串当作属性名的

libin1991

libin1991 commented on Aug 27, 2020

@libin1991

大部分情况.快,不过对JS的v引擎来说配合JIT优化,总体来说不相上下

zizifn

zizifn commented on Dec 11, 2021

@zizifn

这种无论怎么样,时间都是一个量级吧,O(n)或者O(2n)时间复杂度都是n啊。在统计上都是一个量级,比较没有太大意义。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @zizifn@wingmeng@zeroone001@LiuMengzhou@Zephylaci

        Issue actions

          第 65 题: a.b.c.d 和 a['b']['c']['d'],哪个性能更高? · Issue #111 · Advanced-Frontend/Daily-Interview-Question