为什么按键搜索对象中的值的速度比在 js 中使用 "in" 要慢?

共4个回答,已解决, 标签: 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, '<

"结果是

5 ' < 这不是很奇怪吗? "

第1个答案(采用)

这是因为 JIT 编译器的工作原理。

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

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

5 "

节点输出:

5 '

但是, 当反转这两个变体时:

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, '

输出:

{ txt: 5 } '

正如您所看到的, 首先执行的版本比第二个版本所需的时间要长得多。

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

第2个答案

您的程序中出现错误

if (a[key].txt = 5)

您没有检查 txt 属性是否等于 5。您将属性设置为 5, 这意味着您是在第一次执行循环后完成的。

第3个答案

正如您在这里所看到的, 使用 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');
}
第4个答案

在 JavaScript 中, 您可以动态地添加或删除对象的属性。Hashmap 是访问属性的最高效、最快速的数据结构。但 JavaScript 的动态特性使其变得更加困难和缓慢。为了解决这个问题, Nodejs V8 引擎内部使用 JavaScript 隐藏类和内联缓存。这两个主题在这个答案中都是相当广泛的解释。因此, 请找到博客链接在这里和以下是 nodejs v8 引擎性能视频的真解释。

在一次迭代中, 您无法确定几乎 99% 的情况下两种算法的性能。因此, 我刚刚修改了您的代码, 并迭代了 11 次 (这也是不够的), 用于演示目的。你可以看到输出的剧烈变化。

<= 10;="" i++)="" {="" const="" a="{" a:="" {="" txt:="" 1="" },="" b:="" {="" txt:="" 2="" },="" c:="" {="" txt:="" 3="" },="" d:="" {="" txt:="" 4="" },="" e:="" {="" txt:="" 5="" },="" f:="" {="" txt:="" 6="" }="" };="" console.time('hash="" map="" access');="" let="" n="a['e'].txt;" console.log(n,="">

以下是产出。

5 '

如果您观察到的输出哈希地图访问有剧烈的变化, 首先它是 8.80 毫秒在第二次它是 0.177 毫秒。你可以发现, 第一次哈希地图后几乎比 "在循环中" 更快。(有时它不是因为我的系统承受了很大的压力, 而运行代码:))

我还颠倒了顺序, 我先把 "For for 在循环中", 然后对象 [哈希图] 以下的结果。

{ txt: 5 } '

我们可以看到, 第一个入路采用了 16.39 毫秒, 而第二个循环只需要 0.266 毫秒。正如上面提到的答案实例化需要很多时间, 我们可以通过看到这些数字轻松地进行验证。

结论是在为 nodejs v8 引擎编写 JavaScript 代码时, 如果我们不添加删除对象上的属性, 它将更快、更高效。此外, 代码实例化在第一次运行时还需要大量的时间。

相关问题

如何从异步调用返回响应? 循环中的 JavaScript 闭包--简单的实际示例 如何从异步调用返回响应? Node 服务器将 Http 响应代码400返回到 Java 为什么按键搜索对象中的值的速度比在 js 中使用 "in" 要慢? 如何监控 RXJS 订阅数量?