我一直在阅读有关在我的 Ruby/Rails 应用程序中减少内存使用的方法,mentioned 的一件事是卡住对象。我已经尝试了下面的代码(MRI,Ruby 2.3.3),根据事件监视器的说法,与不卡住字符串相比,它确实节省了内存。
pipeline = []
100_000.times { pipeline << 'hello world'.freeze }
但是,如果我对散列文字进行相同的尝试,它会使用大量内存,除非我将散列分配给一个变量并在之前卡住它。
pipeline = []
100_000.times { pipeline << {hello: 'world'}.freeze } # Uses about 25MB
my_hash = {hello: 'world'}
my_hash.freeze
100_000.times { pipeline << my_hash} # This uses about 1MB
谁能解释为什么?我一直认为字符串大小写有点奇怪,因为看起来您只是创建了许多不同的字符串对象,分别卡住每个对象,然后将大量卡住的对象添加到数组中。不知道为什么它有效,但是嘿,它确实有效。现在,哈希大小写更符合我的预期,但我不知道为什么它的行为不像字符串。
最佳答案
可能的情况是 Ruby 优化器可以识别该字符串从一个循环到下一个循环都是相同的,但它无法识别该哈希是相同的,因此它会生成新的哈希。在第二种变体中,您实际上使用相同的散列,以便优化器可以处理它。
为了证明,看看这个:
pipeline = []
100_000.times { pipeline << 'hello world'.freeze }
pipeline.map(&:object_id).uniq.length
# => 1
那是一组相同的对象,只有一个分配。
pipeline = []
100_000.times { pipeline << {hello: 'world'}.freeze }
pipeline.map(&:object_id).uniq.length
# => 100000
那是 100,000 个不同的对象。
关于ruby - 为什么卡住哈希文字与卡住字符串文字不同?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45363371/