数组的性能包括vs映射到对象并在JavaScript中访问它

Luk*_* Xu 5 javascript arrays performance json dictionary

根据CS的基本原理,search未排序列表的功能必须在O(n)时间内发生,而对于HashMaps,直接访问数组将在O(1)时间内发生。

那么将数组映射到字典中然后直接访问该元素是否更有效?还是应该只使用include?这个问题是专门针对JavaScript的,因为我相信这将回落到的核心是如何实现的细节includes(){}实现的。

let y = [1,2,3,4,5]
y.includes(3)
Run Code Online (Sandbox Code Playgroud)

要么...

let y = {
          1: true,
          2: true
          3: true
          4: true
          5: true
        }
5 in y
Run Code Online (Sandbox Code Playgroud)

and*_*ter 13

2020/04/29 更新

正如评论者正确指出的那样,V8 似乎正在优化数组包含调用。分配给 var 并使用它的更新版本会产生更多预期结果。在那种情况下,对象地址是最快的,其次是 Set 并且在远处的第三个是 Array 包含(在我的系统/浏览器上)。

尽管如此,我确实坚持我最初的观点,即如果进行微观优化,则值得测试假设。只要确保您的测试有效;)

原来的

好。尽管明显期望 Object address 和 Set 的性能应该优于 Array 包含,但针对 Chrome 的基准测试表明实现胜过预期。

在我与 Chrome Array 对抗的长凳上,包括无疑是表现最好的。

我也在本地用 Node 进行了测试,得到了更多预期的结果。在那个 Object 地址获胜,紧随其后的是 Set has,然后 Array 包含的速度比两者都慢。

底线是,如果您要进行微优化(不推荐),则值得进行基准测试,而不是假设哪种可能最适合您的特定情况。正如您的问题所暗示的那样,最终归结为实施。因此,针对目标平台进行优化是关键。

这是我得到的结果:

节点(12.6.0):

ops for Object address 7804199
ops for Array includes 5200197
ops for Set has        7178483
Run Code Online (Sandbox Code Playgroud)

铬(75.0):https :
//jsbench.me/myjyq4ixs1/1

对 Chrome 的基准测试

  • 您的测试用例包含非常小的项目集,并且您不使用检查结果,因此我敢打赌 JS JIT 只是优化了 array.includes 情况下的访问。如果您使用更大的样本量并使用检查结果,对于字符串集,Set has 操作比 Array.includes 快 40-100 倍以上(在 macOS 上的 Chrome 和 Firefox 上测试)。https://jsbench.me/t4k9lk7h7j/1 - 即使这个版本也有问题,因为我们没有测试负查找(即不在列表中的项目)的速度。 (10认同)

Cer*_*nce 5

该对象的查找线性时有发生,因此使用的不是数组对象属性的确是一种选择,但如果你只是想检查一个值是否包含在集合中,它会使用更合适Set,这是值的(通常是无序的)集合,也可以在线性时间内查找它们。(相反,使用普通对象将要求您除了键之外还具有其他,而这些键您根本不在乎-因此,请改用a Set。)

const set = new Set(['foo', 'bar']);
console.log(set.has('foo'));
console.log(set.has('baz'));
Run Code Online (Sandbox Code Playgroud)

当您必须为同一个查询多个值时,这将很有用Set。但是,向中添加项目Set(就像向对象中添加属性一样)是O(N),因此,如果您只想查找一个值,一次,这对对象技术都不会有好处,您也可以使用数组includes测试。

  • 请参阅 https://www.ecma-international.org/ecma-262/6.0/#sec-set-objects - “集合对象必须使用哈希表或其他机制来实现,这些机制平均提供次线性的访问时间关于集合中元素的数量。”。通常是 [`O(1)`](/sf/ask/2352805661/) (3认同)