On 01 Jun 2005, at 18:36, Gyoung-Yoon Noh wrote: > OK, you're right in case of String#gsub and String#gsub!. > But not 'a lot slower' but 'a little slower'. > > $ cat destructive.rb > require 'benchmark' > > Benchmark.bmbm do |bm| > bm.report("Destructive") do > 100.times do > str = (0..10000).to_a.join('-') > str.gsub!(/\d+/, '-') > end > end > bm.report("Non-destructive") do > 100.times do > str = (0..10000).to_a.join('-') > str = str.gsub(/\d+/, '-') > end > end > end > > $ ruby destructive.rb > Rehearsal --------------------------------------------------- > Destructive 4.240000 0.010000 4.250000 ( 4.448997) > Non-destructive 4.250000 0.010000 4.260000 ( 4.279959) > ------------------------------------------ total: 8.510000sec > > user system total real > Destructive 4.260000 0.010000 4.270000 ( 4.378810) > Non-destructive 4.230000 0.010000 4.240000 ( 4.305321) The difference is not in the speed of the operations themselves, it is in the memory pressure on the GC. Your benchmark is not a fair comparison between the two because it ignores the side-effect of memory pressure and does not fit with the way you would use chaining vs !. This benchmark more realisticly shows the effects of memory pressure and is more fitting with how you would really use chaining vs !: $ cat sub.rb require 'benchmark' N = 10_000 STR = (0..N).to_a.join('-') Benchmark.bmbm do |bm| bm.report("Base") do str = STR.dup N.times { } end bm.report("Destructive") do str = STR.dup N.times { str.sub!(/\d+/, '-') } end bm.report("Non-destructive") do str = STR.dup N.times { str = str.sub(/\d+/, '-') } end end $ ruby sub.rb Rehearsal --------------------------------------------------- Base 0.000000 0.000000 0.000000 ( 0.003034) Destructive 1.470000 1.380000 2.850000 ( 3.266492) Non-destructive 1.930000 2.740000 4.670000 ( 5.584387) ------------------------------------------ total: 7.520000sec user system total real Base 0.000000 0.000000 0.000000 ( 0.002857) Destructive 1.460000 1.400000 2.860000 ( 3.383933) Non-destructive 1.910000 2.800000 4.710000 ( 5.688635) > I don't understand what exactly this difference implies. Your benchmark wasn't helpful in revealing the true difference between the two methods. As you can see, the non-destructive case takes much more time in user space because the GC has to clean up all the temporary strings. It also takes ~33% more time in general because of the GC. > Does that mean Ruby's String is much alike raw C string? It wraps a C string. > Or is there any particular optimization for String copy? Certain operations are COW. -- Eric Hodel - drbrain / segment7.net - http://segment7.net FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04