ruby - Why freezing hash literal is not the same as freezing string literal? -
i have been reading ways reduce memory usage in ruby/rails app, , 1 thing mentioned freezing objects. have tried code below (mri, ruby 2.3.3) , save memory, according activity monitor, compared not freezing string.
pipeline = [] 100_000.times { pipeline << 'hello world'.freeze }
however, if try same hash literal, uses lots of memory, unless assign hash variable , freeze before.
pipeline = [] 100_000.times { pipeline << {hello: 'world'}.freeze } # uses 25mb my_hash = {hello: 'world'} my_hash.freeze 100_000.times { pipeline << my_hash} # uses 1mb
can explain why? thought string case bit strange, because looks you're creating lots of different string objects, freezing each 1 separately, , adding lots of frozen objects array. don't know why works, hey, did. now, hash case more in line expected, don't know why won't behave string.
it's case ruby optimizer can identify string being same 1 loop next, it's unable identify hash being identical makes new ones. in second variant literally use same hash optimizer can handle it.
for proof, @ this:
pipeline = [] 100_000.times { pipeline << 'hello world'.freeze } pipeline.map(&:object_id).uniq.length # => 1
that's array of identical objects, 1 allocation only.
pipeline = [] 100_000.times { pipeline << {hello: 'world'}.freeze } pipeline.map(&:object_id).uniq.length # => 100000
that's 100,000 different objects.
Comments
Post a Comment