From: Gyoung-Yoon Noh Date: 2005-06-02T13:52:21+09:00 Subject: Re: Method Chaining Issues Eric, thank you for kind explanation. It helps me. I have been reading ruby source code with very lazy mode. I need a kind of booster reading engine. ;-) On 6/2/05, Eric Hodel wrote: > 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 > > > -- http://nohmad.sub-port.net