lua*_*ped 3 v8 spidermonkey time-complexity chakra ecmascript-6
在 ES6 中,Maps 和 Sets 可以使用 Objects 作为键。然而,由于 ES6 规范没有规定这些数据结构的底层实现,我想知道现代 JS 引擎如何存储密钥以保证 O(1) 或至少是次线性 检索?
在像 Java 这样的语言中,程序员可以明确提供一个(好的)hashCode 方法,该方法将在键空间中均匀地散列键,以保证性能。然而,既然 JS 没有这样的特性,那么假设它们在 Maps 和 Sets 实现中仍然使用某种散列是否仍然公平?
任何信息将不胜感激!
是的,该实现基于散列,并且具有(摊销)恒定访问时间。
“他们使用对象身份”是一种简化;完整的故事是 ES Maps 和 Sets 使用SameValueZero算法来确定相等性。
与此规范一致,V8 的实现计算字符串和数字的“真实”散列,并选择一个随机数作为对象的“散列”,将其作为私有(隐藏)属性存储在这些对象上以供以后访问。(这不是很理想,将来可能会改变,但现在就是这样。)
使用memoryAddress % keySpace无法工作,因为垃圾收集器会四处移动对象,并且每次可能移动任何对象时重新散列所有 Maps 和 Sets 将非常复杂和昂贵。