使用fixnums作为Ruby哈希中的键是否合适?

时间:2011-03-30 16:43:13

标签: ruby hash key symbols fixnum

我正在创建一个哈希来表示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转换为字符串然后转换符号,我可以使用符号作为键。然而,这种转换很烦人,曾经有人告诉我实习字符串是低效的。是这样吗?他们看起来很难看。

    fruits = {
      :"23" => "apple",
      :"109" => "orange",
      # ...
      :"23429" => "banana"
    }
    
  4. 使用符号作为键的哈希

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

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

2 个答案:

答案 0 :(得分:5)

我的建议:Hash使用Fixnum键。

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

答案 1 :(得分:2)

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

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