使用 fixnum 作为 Ruby 散列中的键是否合适?
我正在创建一个散列来表示 MySQL 数据库中的一些记录。哈希键对应于数据库 ID 字段,哈希值对应于数据库名称字段。
什么是更好的&为什么?
数组
这可行,但 Ruby 对于稀疏数组似乎效率低下,因为将所有中间索引的值设置为 tp
nil
似乎会产生额外的开销。水果 = [] 水果[23] =“苹果” 水果[109] =“橙色” # ... 水果[23429] = "香蕉"
以fixnum作为键的哈希
我最喜欢这个,但我总是读到最好使用符号作为散列中的键。使用fixnums作为散列中的键是否同样好?我不确定是否是这样,但我认为
34.hash
因为 fixnums 的性质,即34.equal? 34
为真,而"hi".equal? “嗨”
是错误的。水果 = { 23 => “苹果”, 第109章“橙子”, # ... 23429=> “香蕉” }
以固定数字的内部字符串表示形式作为键的哈希
通过将固定数转换为字符串,然后转换为符号,我可以使用符号作为键。然而,这种转换很烦人,有人曾经告诉我,内部字符串效率低下。是这样吗?他们在我看来只是丑陋而已。
水果 = { :“23”=> “苹果”, :“109”=> “橙子”, # ... :"23429" => “香蕉” }
以符号为键的哈希
通过为每个键添加字母字符前缀,我可以获得更漂亮的符号(并且还可以使用新的 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?
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"
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" }
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" }
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的建议:使用带有
Fixnum
键的Hash
。正如你所说,这将允许稀疏对象。有一些特殊的速度和内存优化适用于
Fixnum
。他们按预期进行比较并转换为所有内容。它应该比符号更快、更简单,并且您不会遇到通常无法解析的驻留字符串的奇怪情况。My suggestion: use a
Hash
withFixnum
keys.As you say, this will allow a sparse object. There are special speed and memory optimizations that apply to
Fixnum
s. 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.据我所知,原因是
symbol.hash
是常量,因此在符号上调用hash
是一个简单的属性查找,而且速度相当快;符号针对此特定用途进行了优化。需要计算字符串的哈希值,因此在字符串上调用hash
涉及实际工作,并且字符串似乎不会缓存其哈希值。 Fixnum 的哈希值似乎是通过对 Fixnum 的内部对象 ID(常量)进行一些简单的位修改来计算的,因此它也应该很快。不要将这些视为权威,我只是快速回顾了 1.9.2 源代码,但我并不是 Ruby 内部的专家。也就是说,我会使用 Fixnums 作为哈希键。这为您提供了稀疏数组的自然表示,并且在内存方面也很高效。任何速度差异都可能是无关的噪音。因此,当出现真正的速度问题时,请采用最清晰的方法并担心优化。
AFAIK the reasoning is that
symbol.hash
is constant so callinghash
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 callinghash
on a string involves real work and strings don't appear to cache their hash values. Thehash
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.