【问题标题】:JavaScript Map much slower than Object for random look-ups?对于随机查找,JavaScript Map 比 Object 慢得多?
【发布时间】:2017-11-03 09:59:20
【问题描述】:

考虑以下两个 sn-ps(来自this jsperf entry):

let val = 0;
for(let i of indices) {
  val += map.get(i);
}
// ---
let val = 0;
for(let i of indices) {
  val += obj[i];
}

这里,map 是一个 Mapobj 是一个普通的旧 JavaScript 对象 (let obj = {}),indices 是一个随机索引数组。 objmap 都已预先填充了数据,因此查找实际上会返回数据。查看 jsperf 以获取完整代码。

问题:

为什么普通的旧 javascript 对象的性能比 Map 高 5 倍以上?这仅仅是因为在撰写本文时,Maps 仍然非常新且未经优化?或者Map 查找中是否存在一些开销,这将始终使其无法像 POJO 一样快?

如果它还没有优化,我们能否期望它比 POJO 更快地进行随机查找最终?为什么?为什么不呢?

【问题讨论】:

  • 我怀疑这是因为方法调用开销。此外,您将集合滥用为数组,仅存储整数索引。对于哪些属性访问是超级优化的。尝试使用某种类型的密钥。
  • @Bergi 修复了数组(虽然要清楚,它与这个问题无关)干杯????这个问题所指的比较是 POJO 与 Map 查找速度。您是说地图可能不如整数索引的 POJO 优化?或者这只是一个侧面的想法,你说这一切(很可能)是由于方法调用开销?
  • 我猜两者都是。您也可以尝试通过执行obj = {get(p) { return this[p]; }}; 并调用obj.get(i) 来模拟开销,但是microbenchmarks easily fool us
  • 最初没有看到您的编辑。尝试使用字符串键并添加了很棒的 obj.get(i) 建议,看起来你是对的! jsperf.com/map-vs-pojo-lookups 所以最初的难题是 POJO 在内部针对整数进行了优化(基本上被转换为数组),以及方法调用开销。随意发布带有该 jsperf 链接的答案。感谢您的帮助!

标签: javascript ecmascript-6


【解决方案1】:

感谢@Bergi 的回答。

Map 相比,纯 JavaScript 对象在初始 jsperf 中表现如此出色的原因是,在引擎盖下,JS 引擎可以看到我们正在使用该对象,就像它是一个数组(连续整数键),所以它“假设”它是一个数组,并且可以在此基础上进行大量优化。 Map 并非如此。

Map 的另一个缺点是它需要方法调用 (map.get(p)),而不是直接属性查找 (obj[p])。这还没有(不能?)优化掉,如下 jsperf 所示:http://jsperf.com/map-vs-pojo-lookups

【讨论】:

  • 链接已失效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 2023-03-14
相关资源
最近更新 更多