Modifying Objects in Place

Every time you create or copy something in memory, you add work for GC. Here are some tips from the book Ruby Performance Optimization to write code without using too much memory.

Modify strings in-place.

Instead of making a changed copy, you change the original string. Look for “bang!” functions, such as trim!, gsub!, slice! etc. Use them when you don’t need the original string.

require_relative "./wrapper" # see above for wrapper script

def modify_strings_in_place
  str = "X" * 1024 * 1024 * 10
  measure("copy") { tmp = str.downcase }
  measure("in-place") { str.downcase! }


# Output
# {"3.0.2":{"gc":"disabled","time":0.01,"gc_count":0,"memory":"10 MB"}}
# {"3.0.2":{"gc":"disabled","time":0.01,"gc_count":0,"memory":"0 MB"}}

Use the shift operator << to append strings, instead of using +=.

When you use +=, Ruby creates an intermediate string and assigns it to the original string after appending.

def append_to_string
  measure do
    x = "foo"
    100_000.times { x += "bar" }

  measure do
    x = "foo"
    100_000.times { x << "bar" }


# Output
# {"3.0.2":{"gc":"disabled","time":9.42,"gc_count":0,"memory":"6412 MB"}}
# {"3.0.2":{"gc":"disabled","time":0.01,"gc_count":0,"memory":"-2 MB"}}

Modify Arrays in-place.

Do not create a modified copy of the same array unless really necessary.

def modify_array_in_place
  data = { "x" * 1024 * 1024 }

  measure { { |str| str.upcase } }
  measure { { |str| str.upcase! } }


# Output
# {"3.0.2":{"gc":"disabled","time":0.12,"gc_count":0,"memory":"100 MB"}}
# {"3.0.2":{"gc":"disabled","time":0.1,"gc_count":0,"memory":"0 MB"}}

Hope that helps.

Subscribe to Akshay's Blog

Sign up now to get access to the library of members-only issues.
Jamie Larson