From: Robert Klemme Date: 2008-03-08T00:02:07+09:00 Subject: Re: duplicating characters in a string 2008/3/6, Joel VanderWerf : > Rodrigo Bermejo wrote: > > "abc".gsub(/./) { |x| x * 2 } > > > That's the most elegant way to refer to captures, but if speed matters: > > "abc".gsub(/(.)/, "\\1\\1") > > The "\\1" is always easy to mess up, which is why I generally prefer the > block form. > > It's only about a factor of two faster, according to the following, but > that matters sometimes. > Rehearsal --------------------------------------------------- > s.gsub(re){...} 5.970000 0.000000 5.970000 ( 6.009089) > s.gsub(re,...) 2.900000 0.060000 2.960000 ( 3.148006) > ------------------------------------------ total: 8.930000sec > > user system total real > s.gsub(re){...} 5.760000 0.010000 5.770000 ( 5.925049) > s.gsub(re,...) 2.800000 0.060000 2.860000 ( 2.914432) What version did you test with? I get much more dramatic differences: 15:56:11 ~ $ ruby /c/Temp/gs.rb Rehearsal ----------------------------------------------------------- s.gsub(re){|x| x * 2} 25.313000 0.031000 25.344000 ( 25.354000) s.gsub(re){|x| x << x} 22.812000 0.000000 22.812000 ( 22.845000) s.gsub(re, '\1\1') 6.516000 0.015000 6.531000 ( 6.539000) s.gsub(re, '\&\&') 6.578000 0.016000 6.594000 ( 6.595000) s.gsub(/./){|x| x * 2} 25.172000 0.016000 25.188000 ( 25.182000) s.gsub(/./){|x| x << x} 22.843000 0.000000 22.843000 ( 22.857000) s.gsub(/(.)/, '\1\1') 6.344000 0.015000 6.359000 ( 6.355000) s.gsub(/./, '\&\&') 6.188000 0.032000 6.220000 ( 6.217000) ------------------------------------------------ total: 121.891000sec user system total real s.gsub(re){|x| x * 2} 25.484000 0.015000 25.499000 ( 25.502000) s.gsub(re){|x| x << x} 22.813000 0.031000 22.844000 ( 22.856000) s.gsub(re, '\1\1') 6.312000 0.000000 6.312000 ( 6.337000) s.gsub(re, '\&\&') 6.359000 0.000000 6.359000 ( 6.359000) s.gsub(/./){|x| x * 2} 25.922000 0.000000 25.922000 ( 25.994000) s.gsub(/./){|x| x << x} 22.672000 0.015000 22.687000 ( 22.707000) s.gsub(/(.)/, '\1\1') 6.375000 0.016000 6.391000 ( 6.389000) s.gsub(/./, '\&\&') 6.235000 0.000000 6.235000 ( 6.239000) 16:00:22 ~ $ ruby -v ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-cygwin] 16:00:26 ~ $ cat /c/Temp/gs.rb require 'benchmark' s = ("abc" * 1_000_000).freeze re = /(.)/ re2 = /./ Benchmark.bmbm do |b| b.report("s.gsub(re){|x| x * 2}") do s.gsub(re) { |x| x * 2 } end b.report("s.gsub(re){|x| x << x}") do s.gsub(re) { |x| x << x } end b.report("s.gsub(re, '\\1\\1')") do s.gsub(re, "\\1\\1") end b.report("s.gsub(re, '\\&\\&')") do s.gsub(re, "\\&\\&") end b.report("s.gsub(/./){|x| x * 2}") do s.gsub(/./) { |x| x * 2 } end b.report("s.gsub(/./){|x| x << x}") do s.gsub(/./) { |x| x << x } end b.report("s.gsub(/(.)/, '\\1\\1')") do s.gsub(/(.)/, "\\1\\1") end b.report("s.gsub(/./, '\\&\\&')") do s.gsub(/./, "\\&\\&") end end 16:00:31 ~ $ Kind regards robert -- use.inject do |as, often| as.you_can - without end