【问题标题】:JavaScript Objects as Hashes? Is the complexity greater than O(1)?JavaScript 对象作为哈希?复杂度是否大于 O(1)?
【发布时间】:2012-09-03 03:33:48
【问题描述】:

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

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

【问题讨论】:

  • 如果您想通过某个字段查找您的对象,为什么还要关心添加和删除? ID 不应在对象实例化后更改。
  • @aviad 我想添加和删除没什么大不了的。我没有看到超过几百万对的用例,尤其是对于这个用例来说,这很可能是荒谬的。再说一次,人们可能希望将此特定功能用于其他事情。我想提供一些指导。
  • “使用对象中的成员变量作为键值对” - 这就是“成员变量”的含义,不是吗?
  • @nnnnnn 好吧,我不一定看到任何关于性能的保证。它们是键值对,但您可以对任何语言的任何变量都这么说。
  • “它们是键值对,但你可以说任何语言的任何变量” - 不,你不能:在大多数语言中,字符串、数字和布尔值是只是没有关联键的值。我的观点是 JS 对象的工作是保存键/值对的集合(其中值可能是对函数或其他对象的引用)。我知道这对您关于性能的问题没有帮助。

标签: javascript performance


【解决方案1】:

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

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

读取这些测试的方法是,如果对象大小增长时 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 键)

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

【讨论】:

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

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

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

【讨论】:

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

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

【讨论】:

  • 这不是一个很好的解释......你可以在后台拥有任何数据结构,仅仅因为接口是基于键/值的并不能保证 O(1) 查找
猜你喜欢
  • 2020-09-11
  • 2017-07-10
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多