title: Why is modifying a Ruby string in-place so slow?
body: <p>I'm curious if somebody can explain why modifying a Ruby string in-place is so slow.  Consider changing the x's in a long string to y's.  Here's one way:</p>
  
  <pre><code>s = "x"*1000000
  s = s.chars.map {|c| c == "x" ? "y" : c }.join
  </code></pre>
  
  <p>And another:</p>
  
  <pre><code>s = "x"*1000000
  s = (0...s.length).map {|i| s[i] == "x" ? "y" : s[i] }.join
  </code></pre>
  
  <p>These both finish in &lt;0.25 seconds.  Now consider:</p>
  
  <pre><code>s = "x"*1000000
  (0...s.length).each do |i|
    s[i] = "y" if s[i] == "x"
  end
  </code></pre>
  
  <p>This takes 60 seconds, an increase factor of 250x.</p>
  
  <p>Please do NOT, repeat, do NOT answer that there are faster ways of changing x's to y's using Regexp, or String#gsub, or String#tr, or whatever.  That's not the question.  This is an abstraction of a larger, complex computation.  The question is, it would seem to be faster to modify a string in-place than to break a string into an array of strings, create a new array of strings, and join those back together.  Yet it's not.</p>
  
  <p>Further, this behavior is not seen with, say arrays of integers.  Using the third approach on an array of integers is just as fast as the first two approaches.  It seems peculiar to strings.</p>