From: Robert Klemme Date: 2009-03-05T21:33:35+09:00 Subject: Re: Cut a string each 80 character --------------090603070207090109050701 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 05.03.2009 12:32, lasitha wrote: > On Thu, Mar 5, 2009 at 2:00 PM, Gennady Bystritsky > wrote: >>> -----Original Message----- >>> From: Leo [mailto:minilith@gmail.com] >>> Sent: Wednesday, March 04, 2009 9:53 PM >>> >>>> string.scan(%r{.{1,80}}).map { |_chunk| >>>> _chunk + '
' >>>> } >>> Isn't that pretty much the same as: >>> >>> string.gsub(%r{.{1,80}}, "\\0
") >> [...] >> The latter may be faster, though. > > Doesn't appear to be. > http://gist.github.com/74249 > > I threw in a primitive insert loop for comparison and was a little > surprised to find it considerably slower than both the others. > > ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-darwin8.11.1] > user system total real > with_scan 0.750000 0.040000 0.790000 ( 0.851104) > with_gsub 0.840000 0.060000 0.900000 ( 0.950050) > with_insert 2.000000 0.050000 2.050000 ( 2.210962) There is an inconsistency in your test: the gsub version creates the second argument to gsub over and over again. You should rather define a constant for that as well. You could do that as well for the sanity check string. With the attached changed script this is what I get: [robert@ora01 ~]$ allruby bm.rb ruby 1.8.5 (2006-08-25) [i386-linux] Rehearsal ----------------------------------------------- with_scan 1.770000 0.040000 1.810000 ( 1.821903) with_gsub 1.720000 0.010000 1.730000 ( 1.750455) with_insert 9.230000 0.000000 9.230000 ( 9.228760) ------------------------------------- total: 12.770000sec user system total real with_scan 1.730000 0.010000 1.740000 ( 1.741069) with_gsub 1.730000 0.010000 1.740000 ( 1.741975) with_insert 9.130000 0.000000 9.130000 ( 9.130356) ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux] Rehearsal ----------------------------------------------- with_scan 1.040000 0.010000 1.050000 ( 1.043332) with_gsub 1.100000 0.010000 1.110000 ( 1.120970) with_insert 9.030000 0.000000 9.030000 ( 9.077018) ------------------------------------- total: 11.190000sec user system total real with_scan 1.030000 0.000000 1.030000 ( 1.031019) with_gsub 1.090000 0.010000 1.100000 ( 1.105150) with_insert 9.040000 0.000000 9.040000 ( 9.049539) [robert@ora01 ~]$ CentOS 5.2 in VM. Kind regards robert --------------090603070207090109050701 Content-Type: text/plain; name="bm.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="bm.rb" require 'benchmark' S = ('0123456789' * (8 * 1_000)).freeze R = '
'.freeze GS = "\\&#{R}".freeze SANE = '
0123456789'.freeze REP = 500 DELTA = 80 + R.length def with_scan s s = s.scan(/.{80}/).join(R) raise 'with_scan failed' unless s[-85..-71] == SANE s end def with_gsub s s = s.gsub(/.{80}/, GS).chomp!(R) raise 'with_gsub failed' unless s[-85..-71] == SANE s end def with_insert s s = s.dup i = 80 while i < s.length s.insert i, R i += DELTA end raise 'with_insert failed' unless s[-85..-71] == SANE s end Benchmark.bmbm do |bm| bm.report('with_scan ') { REP.times { with_scan S }} bm.report('with_gsub ') { REP.times { with_gsub S }} bm.report('with_insert') { REP.times { with_insert S }} end --------------090603070207090109050701--