【问题标题】:Performance of `Hash#has_key?` and `Array#index``Hash#has_key?` 和 `Array#index` 的性能
【发布时间】:2015-04-21 10:56:05
【问题描述】:

我经常检查一个特定的值是否在一个大数组中。我可以通过Array#index 做到这一点。为了提高效率,我创建了一个数组值的散列并调用Hash#has_key?

  • 方法一

    arr = ["a","b","c","d"]
    arr.index("c")
    
  • 方法二

    h = {"a"=> true, "b"=> true, "c"=> true, "d"=> true}
    h.has_key?("c")
    

但我注意到,如果键不在给定的哈希中,ruby 会抛出异常。我想知道这两种方法的相对性能是什么。

【问题讨论】:

  • 为什么不自己找出最适合您情况的方法呢? ruby-doc.org//stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.html
  • 不知道为什么你认为 ruby​​ 会在密钥不在散列中时抛出异常(除非你故意使用h.fetch
  • h["a"] 不会在您的示例代码中引发异常;它只会返回nil
  • 奇怪...由于某种原因,当我第一次尝试时,我获得了豁免。原来我忘记了“?”在 has_key 中,并没有很好地注意错误。对不起!
  • 你的意思不是很清楚。是您的第二种方法引发错误的问题吗?那部分没有复制。如果您的问题仅与性能有关,那么您应该删除第一点。

标签: ruby arrays performance hash


【解决方案1】:

要回答您的问题,“方法 2”应该更快。现在,这是一个负载很大的语句,部分取决于哈希的本质(例如collisions when inserting)。

但是,对于您的特定用例,我认为数组和哈希都是“错误的工作工具”。一般来说,如果您使用哈希来检查唯一集是否存在(提示),请使用set

最后一个想法,可能有价值也可能没有价值,具体取决于您的示例的设计程度。如果您要存储一些有限的有序值集(在您的示例中为“a”-“d”),则数组绝对是要走的路。为什么?因为您可以轻松地将字母表的值映射到数组索引(例如,a 映射到 0,b 映射到 1 等等),在您的情况下,通过将字母转换为 ascii 并减去以获得它们所需的位置。这将为您提供 O(1) 查找时间。

【讨论】:

  • 想一想,集合肯定是理想的数据结构。所有的答案都差不多,但你会得到第一名的支票!谢谢!
  • “[C] 将字母转换为 ascii 并减去以获得所需的位置”是一个丑陋的 hack。它不是 Ruby 风格的。
  • @sawa 这到底是什么意思?当您担心性能时,“丑陋的黑客”是标准程序。
【解决方案2】:

Ruby 在标准库中有一个构造,可以为您提供所需的内容:使用 #include? 进行 O(1) 次查找。

Set class documentation

require 'set'
arr = ["a","b","c","d"]
set = Set.new(arr)
set.include?("c")

但是请注意,这仅在您不关心重复元素时才有效(但我假设这是基于您的第二种方法的情况,这也取决于该假设)。

【讨论】:

    猜你喜欢
    • 2014-09-12
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    相关资源
    最近更新 更多