使用 fixnum 作为 Ruby 散列中的键是否合适?

发布于 2024-10-27 12:45:14 字数 996 浏览 7 评论 0原文

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

什么是更好的&为什么?

  1. 数组

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

    水果 = []
    水果[23] =“苹果”
    水果[109] =“橙色”
    # ...
    水果[23429] = "香蕉"
    
  2. 以fixnum作为键的哈希

    我最喜欢这个,但我总是读到最好使用符号作为散列中的键。使用fixnums作为散列中的键是否同样好?我不确定是否是这样,但我认为 34.hash 因为 fixnums 的性质,即 34.equal? 34 为真,而 "hi".equal? “嗨” 是错误的。

    水果 = {
      23 => “苹果”,
      第109章“橙子”,
      # ...
      23429=> “香蕉”
    }
    
  3. 以固定数字的内部字符串表示形式作为键的哈希

    通过将固定数转换为字符串,然后转换为符号,我可以使用符号作为键。然而,这种转换很烦人,有人曾经告诉我,内部字符串效率低下。是这样吗?他们在我看来只是丑陋而已。

    水果 = {
      :“23”=> “苹果”,
      :“109”=> “橙子”,
      # ...
      :"23429" => “香蕉”
    }
    
  4. 以符号为键的哈希

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

    水果 = {
      i23:“苹果”,
      i109:“橙色”,
      # ...
      i23429:“香蕉”
    }
    

I'm creating a hash to represent a few of the records in a MySQL database. The hash keys corresponds to the database ID fields and the hash values correspond to the database name fields.

What's better & why?

  1. Array

    This works, but Ruby seems inefficient with sparse arrays because it appears that there's the extra overhead of setting the values of all intermediary indexes tp nil.

    fruits = []
    fruits[23] = "apple"
    fruits[109] = "orange"
    # ...
    fruits[23429] = "banana"
    
  2. Hash with fixnum as keys

    I like this the best, but I've always read it's best to use symbols as keys in a hash. Is it equally as good to use fixnums as keys in a hash? I'm not sure if it is, but I think 34.hash because of the nature of fixnums, i.e., 34.equal? 34 is true whereas "hi".equal? "hi" is false.

    fruits = {
      23 => "apple",
      109 => "orange",
      # ...
      23429 => "banana"
    }
    
  3. Hash with interned string representations of fixnums as keys

    By converting the fixnums to strings and then symbols, I'm able to use symbols as keys. This conversion, however, is annoying, and someone once told me that interning strings is inefficient. Is that so? They just look ugly to me.

    fruits = {
      :"23" => "apple",
      :"109" => "orange",
      # ...
      :"23429" => "banana"
    }
    
  4. Hash with symbols as keys

    I can get prettier symbols (and also use the new Ruby 1.9 hash syntax) by prefixing each key with an alpha character, but then, this solution also requires conversion.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无所谓啦 2024-11-03 12:45:14

我的建议:使用带有 Fixnum 键的 Hash

正如你所说,这将允许稀疏对象。有一些特殊的速度和内存优化适用于 Fixnum。他们按预期进行比较并转换为所有内容。它应该比符号更快、更简单,并且您不会遇到通常无法解析的驻留字符串的奇怪情况。

My suggestion: use a Hash with Fixnum keys.

As you say, this will allow a sparse object. There are special speed and memory optimizations that apply to Fixnums. They compare as expected and convert to everything. It should be faster and simpler than symbols and you won't have the strangeness of interning strings that couldn't ordinarily have been parsed.

帅气尐潴 2024-11-03 12:45:14

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

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

AFAIK the reasoning is that symbol.hash is constant so calling hash on a symbol is a simple property lookup and quite fast; symbols are optimized for this particular use. The hash value for a string needs to be computed so calling hash on a string involves real work and strings don't appear to cache their hash values. The hash value for a Fixnum appears to be computed with some simple bit mangling on the Fixnum's internal object ID (a constant) so it should also be quick. Don't take any of this as authoritative, I just did a quick review of the 1.9.2 source but I'm hardly an expert on the Ruby internals.

That said, I'd use Fixnums as hash keys. That gives you a natural representation for a sparse array that is also efficient in terms of memory. Any speed differences will probably be irrelevant noise. So, go with the clearest approach and worry about optimization when there is a real speed problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文