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

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -