为什么从 Map 获取比从对象获取慢?

Why is getting from Map slower than getting from object?

我正在考虑将我的状态管理层迁移到使用 Map 而不是使用标准对象。

根据我的阅读,Map 实际上是一个散列 table 而对象在幕后使用 hidden classes。通常建议在可能动态添加或删除属性的地方使用 Map.

更有效

我进行了一些测试,令我惊讶的是 Object 版本中访问值的速度更快。

https://jsfiddle.net/mfbx9da4/rk4hocwa/20/

article also mentions fast and slow properties。也许我在 test1 中的代码示例如此之快的原因是因为它使用了快速属性?这似乎不太可能,因为该对象有 100,000 个键。我如何判断对象是使用快速属性还是字典查找?为什么地图版本会更慢?

是的,在实践中,看起来像是过早的优化,万恶之源……等等。但是,我对内部结构很感兴趣,并且很想知道选择 Map 而不是 Object 的最佳实践。

(此处为 V8 开发人员。)

当心微基准测试,它们通常具有误导性。

V8 的对象系统是这样实现的,因为在许多情况下它非常快——正如您在此处看到的那样。

我们建议将 Map 用于类似地图的用例的主要原因是,当机器的某些部分“过载”时,对象系统可能会表现出非本地性能影响。在像您创建的小测试中,您不会看到这种效果,因为没有其他任何事情发生。在一个大型应用程序中(在许多不同的使用模式中使用许多具有许多属性的对象),它仍然不能保证(因为它取决于应用程序的其余部分正在做什么)但是在适当的地方使用地图很有可能会提高整体性能-- 如果整个系统之前碰巧 运行 陷入其中一种不幸的情况。

另一个原因是 Maps 比 Objects 更好地处理条目删除,因为这是一个用例,它们的实现明确预期是常见的。

也就是说,正如您已经指出的那样,抽象地担心这些细节是一种过早优化的情况。如果您遇到性能问题,那么分析您的应用程序以找出大部分时间花在了哪些地方,然后专注于改进这些方面。如果您最终怀疑对象作为地图的使用导致了问题,那么我建议更改应用程序本身的实现,并测量(使用真实的应用程序!)它是否有所作为。

(请参阅此处了解相关的、同样具有误导性的微基准测试,其中甚至微基准测试本身在经过微小修改后也开始产生相反的结果:Why "Map" manipulation is much slower than "Object" in JavaScript (v8) for integer keys?。这就是为什么我们建议使用真实应用程序进行基准测试,而不是使用简单的微型场景。 )