小编典典

为什么在 Ruby 中使用符号作为哈希键?

all

很多时候人们在 Ruby 哈希中使用符号作为键。

与使用字符串相比有什么优势?

例如:

hash[:name]

对比

hash['name']

阅读 169

收藏
2022-08-29

共1个答案

小编典典

TL;博士:

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

Ruby 符号是不可变的(无法更改),这使得查找内容变得更加容易

简短(ish)答案:

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

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

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

如果您使用字符串作为哈希键,Ruby 需要评估字符串并查看其内容(并在其上计算哈希函数)并将结果与​​已存储在哈希中的键的(哈希)值进行比较.

如果您使用符号作为哈希键,则暗示它是不可变的,因此 Ruby 基本上可以将对象 ID 的(哈希函数)与已经存储在中的键的(哈希)对象 ID
进行比较哈希。(快多了)

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

笔记:

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

如果您访问散列,Ruby 总是应用散列函数从您使用的任何键计算“散列键”。您可以想象像 MD5 哈希这样的东西。然后 Ruby 将这些“散列键”相互比较。

每次在代码中使用字符串时,都会创建一个新实例 - 创建字符串比引用符号要慢。

从 Ruby 2.1 开始,当您使用冻结字符串时,Ruby 将使用相同的字符串对象。这避免了必须创建相同字符串的新副本,并将它们存储在垃圾收集的空间中。

长答案:

https://web.archive.org/web/20180709094450/http://www.reactive.io/tips/2009/01/11/the-
difference-between-ruby-symbols-and-
strings

http://www.randomhacks.net.s3-website-us-
east-1.amazonaws.com/2007/01/20/13-ways-of-looking-at-a-ruby-
symbol/

https://www.rubyguides.com/2016/01/ruby-
mutability/

2022-08-29