JavaScript 对象作为哈希?复杂度是否大于 O(1)?

IT技术 javascript performance
2021-03-16 01:55:39

对于我最近写的一些算法,我认为散列会非常好。我认为我可能只是将对象中的成员变量用作键值对。我不确定这是否是最佳的,因为我真的不知道幕后发生了什么。我还认为 V8 的做法与其他环境不同。但是,我确实认为查找成员变量会很快(希望如此)?

尽管如此,我想知道在 JavaScript 对象中写入、读取、创建和删除成员变量的运行时复杂度是否都是 O(1)。如果环境(v8 与其他)存在差异,它们是什么?

3个回答

是的,它们是哈希。不同浏览器的实现是不同的。尽管许多文章声称对象不是散列,但它们的行为与散列非常相似,因此可以这样使用。

我必须通过运行性能测试来证明这一点:

读取这些测试的方法是,如果对象的大小增加时 ops/sec 没有性能差异,那么这意味着对象是散列。散列的定义特征是每个操作的复杂度都是 O(1),而不管它与其他操作相比更快或更慢。

测试:
http : //jsperf.com/objectsashashes/2(100 个密钥)
http://jsperf.com/objectsashashes/3(100k 个密钥)
http://jsperf.com/objectsashashes/(100 万个密钥)
http:// /jsperf.com/objects-as-hashes-300-mil(10m密钥)

注意:每个浏览器在不同的操作中更快/更慢。这似乎在发布和年复一年之间发生变化。

@yunggun 在创建此帖子时无法保证情况确实如此。事实上,那里存在的所有文章都说“对象不是哈希值,停止像它们一样对待它们”。为了证明情况确实如此,我进行了一些性能测试。它表明一切都是不变的时间确实是正确的。没有规范说这一定是真的(至少我当时找不到)。对象是对象而不是字典,碰巧在 JS 中的常见实现是它们是散列。
2021-04-17 01:55:39
它可能不会影响您的统计数据,但在拆卸函数中,n是未定义的。您指定了一个全局变量,但 jsPerf 已将代码封装在一个函数中。所以这个函数(如果被调用)抛出了一个似乎被 jsPerf 忽略的错误。
2021-04-18 01:55:39
所以总结是所有 CRUD 操作的时间都是恒定的?
2021-04-19 01:55:39
@temporary_user_name 是的!请参阅 Matt Ball 的以下答案。我不知道为什么这个答案是最重要的答案,它并没有真正触及问题的实质。
2021-05-08 01:55:39
@RobG 感谢您的捕获。我对以下内容进行了更新:jsperf.com/objects-as-hashes-100k/2 它似乎对性能影响不大。实际上,它在所有操作中都稍快一些。不断的时间变化。我想我会暂时离开它。虽然,我绝对应该解决这个问题。
2021-05-11 01:55:39

JavaScript 对象散列。我无法想象任何不会对对象属性提供恒定时间 CRUD 操作的理智实现。

您是否发现这种方法存在特定的性能问题?

我可以想象实现可能不一定将 Javascript 对象表示为哈希表 - 例如,JScript.NET 使用了 CLR 的类型系统,这意味着每个字段都是通过内存偏移量而不是哈希表查找来访问的,大概每个对象的修改是使用反射或至少是重新分配。
2021-04-23 01:55:39
@MattBall——ECMAScript 对象被指定为简单的名称/值对,术语“哈希”很可能为某些人推断出更多的功能。也许 javascript 对象在下面实现为散列,谁知道?大卫的评论是公平的——测试一下看看。可能是不同方面在不同浏览器中表现不同。如果与 OP 相关,测试也应该包括一个hasOwnProperty过滤器。
2021-04-26 01:55:39
根据鸽巢原理,在降低性能之前(例如,由于哈希冲突),您可以拥有的成员变量的数量是有限的。但是,除非您故意选择病态的坏对象键并使用大量对象键,否则您将不会看到这种降级。
2021-05-01 01:55:39
我发布了我的分析结果!再次感谢!
2021-05-06 01:55:39
还没有性能问题。我很快就会进行一个更大的测试,正如@David 在评论中提到的那样,我会做一个基准测试。我想这个问题的一部分只是好奇心。我假设因为它的功能类似于散列,所以它是一个散列。虽然不完全确定。另外,我不确定您可能拥有的成员变量数量是否有上限。
2021-05-11 01:55:39

JavaScript 中的对象是哈希表的一个示例,因为对象数据表示为键和值。

这不是一个好的解释......你可以在引擎盖下拥有任何数据结构,仅仅因为接口是基于键/值的并不能保证 O(1) 查找
2021-04-18 01:55:39