为什么通过键在对象中搜索值比在js中使用“ for in”要慢?

Fen*_*jia 29 javascript node.js

为什么通过键在对象中搜索值比for in在JavaScript中使用搜索要慢?

像这样的代码:

const a = { a: { txt: 1 }, b: { txt: 2 }, c: { txt: 3 }, d: { txt: 4 }, e: { txt: 5 }, f: { txt: 6 } };

console.time('1');
let n = a['e'].txt;
console.log(n, '<<n')
console.timeEnd('1');

console.time('2');
for (const key in a) {
    if (a[key].txt == 5) {
        const m = a[key];
        console.log(m, '<<m')
        break;
    }
}
console.timeEnd('2');
Run Code Online (Sandbox Code Playgroud)

结果是

5'<<通过键'
1:2.329毫秒
{txt:5}'<< for in'
2:0.447ms

这不是很奇怪吗?

Seb*_*lor 45

这是因为JIT编译器的工作方式。

当您使用Node启动JS脚本时,V8开始对其进行解释,同时将其编译为本机代码。

在Chrome Devtools控制台中运行它,我得到以下输出:

5 "<<n"
0.167724609375ms
{txt: 5} "<<m"
2: 0.262939453125ms
Run Code Online (Sandbox Code Playgroud)

NodeJS输出:

5 '<<n'
1: 18.684ms
{ txt: 5 } '<<m'
2: 3.713ms
Run Code Online (Sandbox Code Playgroud)

但是当反转两个变体时:

const a = { a: { txt: 1 }, b: { txt: 2 }, c: { txt: 3 }, d: { txt: 4 }, e: { txt: 5 }, f: { txt: 6 } };


console.time('2');
for (const key in a) {
    if (a[key].txt = 5) {
        const m = a[key];
        console.log(m, '<<m')
        break;
    }
}

console.timeEnd('2');
console.time('1');
let n = a['e'].txt;
console.log(n, '<<n')
console.timeEnd('1');
Run Code Online (Sandbox Code Playgroud)

输出:

{ txt: 5 } '<<m'
2: 22.017ms
5 '<<n'
1: 0.245ms
Run Code Online (Sandbox Code Playgroud)

如您所见,第一个执行的版本比第二个执行的时间要长得多。

但是,如果将其平均,则可以看到执行密钥访问比for in循环快得多。

  • “控制台”已经存在,它是本机代码,无需初始化。V8会及时编译您的代码,因此会在编译完成之前对其进行解释,因此“慢速”启动 (2认同)

Mas*_*sim 10

您的程序有错误

if (a[key].txt = 5)
Run Code Online (Sandbox Code Playgroud)

You are not checking if the txt property is equal to 5. You are setting the property to 5 which means you are finished after the first execution of the loop regardless.


Art*_*hur 5

正如您在此处看到的,使用 JS 进行测试可能真的一团糟。

const a = { a: { txt: 1 }, b: { txt: 2 }, c: { txt: 3 }, d: { txt: 4 }, e: { txt: 5 }, f: { txt: 6 } };

let test = function(x) {
  console.log("Test "+x+" times")
  console.time('1');
  for(let i=0;i<x;i++) {
     let n = a['e'].txt;
  }

  console.timeEnd('1');
  console.time('2');

  for(let i=0;i<x;i++) {
    for (const key in a) {
        if (a[key].txt == 5) {
            const m = a[key];
            break;
        }
    }
  } 
  console.timeEnd('2');
}

test(1)
test(100)
test(100000)
test(100000)
test(100000)
test(10000000)
Run Code Online (Sandbox Code Playgroud)