From: Mike Gold Date: 2009-01-23T23:27:59+09:00 Subject: Re: String doesnt auto dup on modification Brian Candler wrote: > > You could try deferring the dup until the first time you call a > destructive method on the string, but the complexity overhead is > unlikely to be worth it. Careful. Intuition is worse than useless here. The only way to know is to measure the particular case in question. class Person def initialize(name) @name = name end def name_cow CopyOnWriteString.new(@name) end def name_dup @name.dup end end require 'benchmark' n = 10_000 sizes = [100, 1000, 10_000, 100_000] objects = sizes.inject(Hash.new) { |acc, size| acc.merge!(size => Person.new("x"*size)) } sizes.each { |size| object = objects[size] puts "-"*40 puts "iterations: #{n} size: #{size}" Benchmark.bm { |x| x.report("cow w/o change") { n.times { object.name_cow } } x.report("dup w/o change") { n.times { object.name_dup } } x.report("cow w/ change") { n.times { object.name_cow << "y" } } x.report("dup w/ change") { n.times { object.name_dup << "y" } } } } ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin] ---------------------------------------- iterations: 10000 size: 100 user system total real cow w/o change 0.031000 0.000000 0.031000 ( 0.031000) dup w/o change 0.032000 0.000000 0.032000 ( 0.031000) cow w/ change 0.171000 0.000000 0.171000 ( 0.172000) dup w/ change 0.047000 0.000000 0.047000 ( 0.047000) ---------------------------------------- iterations: 10000 size: 1000 user system total real cow w/o change 0.032000 0.000000 0.032000 ( 0.031000) dup w/o change 0.046000 0.000000 0.046000 ( 0.047000) cow w/ change 0.172000 0.000000 0.172000 ( 0.172000) dup w/ change 0.063000 0.000000 0.063000 ( 0.062000) ---------------------------------------- iterations: 10000 size: 10000 user system total real cow w/o change 0.031000 0.000000 0.031000 ( 0.032000) dup w/o change 0.109000 0.000000 0.109000 ( 0.109000) cow w/ change 0.282000 0.000000 0.282000 ( 0.281000) dup w/ change 0.156000 0.000000 0.156000 ( 0.156000) ---------------------------------------- iterations: 10000 size: 100000 user system total real cow w/o change 0.031000 0.000000 0.031000 ( 0.032000) dup w/o change 0.672000 0.000000 0.672000 ( 0.672000) cow w/ change 1.406000 0.000000 1.406000 ( 1.406000) dup w/ change 1.219000 0.000000 1.219000 ( 1.219000) Destructive methods are less common in real code, and especially so when the string comes from a attr_reader method. It is likely that the case to optimize is the non-destructive call (the first of each quadruplet above). But we have to profile the specific situation. -- Posted via http://www.ruby-forum.com/.