* Daniel Berger (Mar 20, 2005 01:10):
> > > Unfortunately, the non-destructive versions are still quite
> > > noticeably slower.

> > No they're not.  Where are you getting these assertions from?,

> Oh, I dunno.  Maybe this benchmark?

> The only exception was slice vs. slice!.  No idea what happened there.

Well, with slice!, you have to do more work than doing a slice.  The
reason is that you have to paste together the parts that are still a
part of the string.  With slice you simply return the substring.

For me, next! is also slower than next.

A comment on your benchmark: doesn't it make more sense to do the tests
on new strings each time?  The benchmark should surely be try to
evaluate the merit of returning a new string versus replacing its
contents, right?  With a benchmark that preallocates 'max' copies of
's1' and fetches them from an array for each of the calls to the
respective functions, the times are much more evenly matched:

            user     system      total        real
      capitalize  0.660000   0.000000   0.660000 (  0.675759)
      capitalize!  0.480000   0.010000   0.490000 (  0.494108)
      chomp  0.660000   0.000000   0.660000 (  0.680509)
      chomp!  0.370000   0.000000   0.370000 (  0.370647)
      delete  1.300000   0.000000   1.300000 (  1.296738)
      delete!  1.070000   0.000000   1.070000 (  1.068162)
      downcase  0.630000   0.000000   0.630000 (  0.639248)
      downcase!  0.400000   0.000000   0.400000 (  0.399627)
      gsub  2.710000   0.020000   2.730000 (  2.844503)
      gsub!  2.250000   0.030000   2.280000 (  2.331406)
      lstrip  0.700000   0.000000   0.700000 (  0.705452)
      lstrip!  0.430000   0.000000   0.430000 (  0.424257)
      next  0.570000   0.000000   0.570000 (  0.570100)
      next!  0.720000   0.000000   0.720000 (  0.725646)
      slice  0.850000   0.000000   0.850000 (  0.844139)
      slice!  1.210000   0.000000   1.210000 (  1.217413)
      reverse  0.510000   0.000000   0.510000 (  0.514665)
      reverse!  0.350000   0.000000   0.350000 (  0.349400)
      rstrip  0.660000   0.000000   0.660000 (  0.664235)
      rstrip!  0.370000   0.000000   0.370000 (  0.371327)
      strip  0.550000   0.000000   0.550000 (  0.547162)
      strip!  0.390000   0.000000   0.390000 (  0.390382)
      sub  0.940000   0.000000   0.940000 (  0.938963)
      sub!  0.690000   0.000000   0.690000 (  0.690106)
      swapcase  0.630000   0.000000   0.630000 (  0.630045)
      swapcase!  0.390000   0.000000   0.390000 (  0.392977)
      tr  0.850000   0.000000   0.850000 (  0.852794)
      tr  0.750000   0.000000   0.750000 (  0.751016)
      tr_s  0.850000   0.000000   0.850000 (  0.845268)
      tr_s!  0.690000   0.000000   0.690000 (  0.690721)
      upcase  0.600000   0.000000   0.600000 (  0.606707)
      upcase!  0.390000   0.000000   0.390000 (  0.413688)

Anyway, if you don't like this test, here are the times on my machine
(it seems Ruby on a Linux system runs a lot faster than on a Windows
system, and much more evenly between the two versions of each method):

            user     system      total        real
      capitalize  0.490000   0.000000   0.490000 (  0.488138)
      capitalize!  0.290000   0.000000   0.290000 (  0.286009)
      chomp  0.460000   0.000000   0.460000 (  0.466617)
      chomp!  0.220000   0.000000   0.220000 (  0.219798)
      delete  1.150000   0.000000   1.150000 (  1.153041)
      delete!  0.920000   0.000000   0.920000 (  0.912380)
      downcase  0.490000   0.000000   0.490000 (  0.489456)
      downcase!  0.240000   0.000000   0.240000 (  0.240895)
      gsub  1.250000   0.000000   1.250000 (  1.254223)
      gsub!  0.520000   0.000000   0.520000 (  0.516004)
      lstrip  0.480000   0.000000   0.480000 (  0.485036)
      lstrip!  0.200000   0.000000   0.200000 (  0.198516)
      next  0.410000   0.000000   0.410000 (  0.406751)
      next!  0.430000   0.000000   0.430000 (  0.430365)
      reverse  0.380000   0.000000   0.380000 (  0.384075)
      reverse!  0.190000   0.000000   0.190000 (  0.193044)
      rstrip  0.470000   0.000000   0.470000 (  0.471682)
      rstrip!  0.200000   0.000000   0.200000 (  0.194479)
      slice  0.600000   0.000000   0.600000 (  0.596786)
      slice!  0.960000   0.000000   0.960000 (  0.961636)
      strip  0.470000   0.000000   0.470000 (  0.469545)
      strip!  0.180000   0.000000   0.180000 (  0.185437)
      sub  0.620000   0.000000   0.620000 (  0.620524)
      sub!  0.470000   0.000000   0.470000 (  0.464609)
      swapcase  0.380000   0.000000   0.380000 (  0.380528)
      swapcase!  0.190000   0.000000   0.190000 (  0.192872)
      tr  0.810000   0.000000   0.810000 (  0.818261)
      tr  0.590000   0.000000   0.590000 (  0.615229)
      tr_s  0.850000   0.000000   0.850000 (  0.858405)
      tr_s!  0.590000   0.000000   0.590000 (  0.597201)
      upcase  0.550000   0.000000   0.550000 (  0.578785)
      upcase!  0.250000   0.000000   0.250000 (  0.252732)

I'm not arguing with the fact that for most methods, the destructive
version will be faster.  I'm just saying that the performance difference
between the two isn't that big,
        nikolai

-- 
::: name: Nikolai Weibull    :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA    :: loc atm: Gothenburg, Sweden    :::
::: page: minimalistic.org   :: fun atm: gf,lps,ruby,lisp,war3 :::
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}