【问题标题】:Is it good to use fixnums as keys in a Ruby hash?使用 fixnums 作为 Ruby 哈希中的键是否很好?
【发布时间】:2011-07-26 06:01:07
【问题描述】:

我正在创建一个散列来表示 MySQL 数据库中的一些记录。哈希键对应数据库 ID 字段,哈希值对应数据库名称字段。

什么更好?为什么?

  1. 数组

    这可行,但 Ruby 似乎对稀疏数组效率低下,因为设置所有中间索引 tp nil 的值似乎有额外的开销。

    fruits = []
    fruits[23] = "apple"
    fruits[109] = "orange"
    # ...
    fruits[23429] = "banana"
    
  2. 以fixnum为键的散列

    我最喜欢这个,但我一直认为最好在哈希中使用符号作为键。使用 fixnums 作为哈希中的键是否同样好?我不确定是否是这样,但我认为 34.hash 因为 fixnums 的性质,即 34.equal? 34 是真的,而 "hi".equal? "hi" 是假的。

    fruits = {
      23 => "apple",
      109 => "orange",
      # ...
      23429 => "banana"
    }
    
  3. 以fixnums的内部字符串表示作为键的散列

    通过将 fixnums 转换为字符串和符号,我可以将符号用作键。然而,这种转换很烦人,有人曾经告诉我,实习字符串效率低下。是这样吗?他们只是在我看来很难看。

    fruits = {
      :"23" => "apple",
      :"109" => "orange",
      # ...
      :"23429" => "banana"
    }
    
  4. 以符号为键的散列

    我可以通过在每个键前面加上一个字母字符来获得更漂亮的符号(并且还使用新的 Ruby 1.9 哈希语法),但是,这个解决方案还需要转换。

    fruits = {
      i23: "apple",
      i109: "orange",
      # ...
      i23429: "banana"
    }
    

【问题讨论】:

  • 我真的不明白仅使用符号作为哈希键的原因。您是否有任何链接可以很好地解释为什么会出现这种情况?
  • 这个blog post on understanding Ruby symbols很好地解释了为什么以及何时在字符串上使用符号。还有这个blog post recommends a ruby symbol as an excellent choice for a hash key。但是,fixnums 呢?它们不是与用作哈希键的符号一样好吗?我认为他们是。
  • 谢谢,如果符号在哈希中解决的主要问题是内存管理,那么我认为@DigitalRoss 100% 正确。

标签: ruby hash key symbols fixnum


【解决方案1】:

我的建议:使用 HashFixnum 键。

正如你所说,这将允许稀疏对象。有适用于Fixnums 的特殊速度和内存优化。他们按预期进行比较并转换为所有内容。它应该比符号更快、更简单,而且你不会有通常无法解析的实习字符串的陌生感。

【讨论】:

    【解决方案2】:

    AFAIK 的原因是 symbol.hash 是常量,所以在符号上调用 hash 是一个简单的属性查找并且非常快;符号针对此特定用途进行了优化。需要计算字符串的哈希值,因此在字符串上调用hash 涉及实际工作,并且字符串似乎不会缓存其哈希值。 Fixnum 的hash 值似乎是通过对 Fixnum 的内部对象 ID(一个常量)进行一些简单的位修改来计算的,因此它也应该很快。不要把这些当作权威,我只是快速回顾了 1.9.2 的源代码,但我几乎不是 Ruby 内部的专家。

    也就是说,我会使用 Fixnums 作为哈希键。这为您提供了一个稀疏数组的自然表示,该数组在内存方面也很有效。任何速度差异都可能是无关紧要的噪音。因此,当出现真正的速度问题时,请采用最清晰的方法并担心优化。

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 2018-06-17
      • 2018-02-19
      • 2017-12-10
      • 1970-01-01
      • 2020-07-02
      相关资源
      最近更新 更多