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

标签 ruby string hashmap symbols

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

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

例如:

hash[:name]

对比

hash['name']

最佳答案

长话短说:

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

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

简短(大概)回答:

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

Ruby 中的符号基本上是“不可变字符串” .. 这意味着它们无法更改,并且它意味着在整个过程中多次引用相同的符号源代码,总是存储为相同的实体,例如具有相同的对象 ID。

另一方面,字符串是可变的,它们可以随时更改。这意味着 Ruby 需要将您在整个源代码中提到的每个字符串存储在它的单独实体中,例如如果您在源代码中多次提到一个字符串“name”,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/

关于ruby - 为什么在 Ruby 中使用符号作为哈希键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8189416/

相关文章:

java - 无法从 block 模板引擎检索对象属性

javascript - 在视觉上打乱字符串,同时保持其同样有效

java - Spinner String 项目值获取(不是字符串名称)android

java - 在java中使用嵌套泛型时出现奇怪的结果

ruby - block 中的变量范围

ruby - 最新的 ruby 在哪里 : Ruby gems equivalent of search. cpan.org/recent

ruby-on-rails - Ruby on Rails 教程 Heroku 部署问题

java - 按值集的大小对 HashMap 进行排序

java - 订购 HashMap

ruby-on-rails - 如何记录 Rails 模型中的隐式方法?