且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么在Ruby中使用符号作为散列键?

更新时间:2022-12-10 11:43:32

简短回答:



使用符号不仅可以在比较时节省时间,而且还可以节省内存,因为它们只存储一次。

Ruby中的符号基本上是不可变字符串 ..这意味着它们不能被更改,并且它暗示多次引用时的相同符号在整个源代码中,始终存储为相同的实体,例如具有相同的对象ID。

字符串另一方面是可变的,它们可以随时更改。这意味着Ruby需要将您在源代码中提到的每个字符串存储在其独立的实体中,例如如果您的源代码中提到了多次提到的字符串name,Ruby需要将这些全部存储在单独的String对象中,因为它们稍后可能会更改(这是Ruby字符串的性质)。

如果使用字符串作为Hash键,Ruby需要计算字符串并查看其内容(并计算散列函数),并将结果与​​(散列)值进行比较密钥已存储在哈希中。



如果您使用符号作为哈希键,则隐含它是不可变的,所以Ruby基本上可以比较(散列函数)object-id与已经存储在散列中的(已散列的)对象id对应的键。 (快得多)

缺点:
每个符号在Ruby解释器的符号表中占用一个插槽,永远不会释放。
符号永远不会被垃圾收集。
因此,当你有大量符号时(例如自动生成的符号),角落案例就是一例。在这种情况下,您应该评估这会如何影响您的Ruby解释器的大小。



注释:

$ b

如果您进行字符串比较,Ruby可以仅通过其对象id来比较符号,而无需评估它们。这比比较需要评估的字符串要快得多。



如果你访问一个散列,Ruby总是应用一个散列函数来计算一个散列键无论你使用什么键。你可以想象一个像MD5-hash的东西。然后Ruby比较这些散列键。

http:// www.reactive.io/tips/2009/01/11/the-difference-between-ruby-symbols-and-strings

http://www.randomhacks.net / articles / 2007/01/20/13 -a-ruby-symbol


A lot of times people use symbols as keys in a Ruby hash.

What's the advantage over using a string?

E.g.:

hash[:name]

vs.

hash['name']

Short answer:

Using symbols not only saves time when doing comparisons, but also saves memory, because they are only stored once.

Symbols in Ruby are basically "immutable strings" .. that means that they can not be changed, and it implies that the same symbol when referenced many times throughout your source code, is always stored as the same entity, e.g. has the same object id.

Strings on the other hand are mutable, they can be changed anytime. This implies that Ruby needs to store each string you mention throughout your source code in it's separate entity, e.g. if you have a string "name" multiple times mentioned in your source code, Ruby needs to store these all in separate String objects, because they might change later on (that's the nature of a Ruby string).

If you use a string as a Hash key, Ruby needs to evaluate the string and look at it's contents (and compute a hash function on that) and compare the result against the (hashed) values of the keys which are already stored in the Hash.

If you use a symbol as a Hash key, it's implicit that it's immutable, so Ruby can basically just do a comparison of the (hash function of the) object-id against the (hashed) object-ids of keys which are already stored in the Hash. (much faster)

Downside: Each symbol consumes a slot in the Ruby interpreter's symbol-table, which is never released. Symbols are never garbage-collected. So a corner-case is when you have a large number of symbols (e.g. auto-generated ones). In that case you should evaluate how this affects the size of your Ruby interpreter.

Notes:

If you do string comparisons, Ruby can compare symbols just by their object ids, without having to evaluate them. That's much faster than comparing strings, which need to be evaluated.

If you access a hash, Ruby always applies a hash-function to compute a "hash-key" from whatever key you use. You can imagine something like an MD5-hash. And then Ruby compares those "hashed keys" against each other.

Long answer:

http://www.reactive.io/tips/2009/01/11/the-difference-between-ruby-symbols-and-strings

http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol