[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

RCR 296: Destructive methods return self

Daniel Amelang

3/19/2005 9:34:00 PM

I know that it's not standard policy to announce RCRs on ruby-talk,
but since this has been a topic of conversation (debate, polemic,
death threats?) lately on this list, I thought it relevant.

RCR 296: Destructive methods return self

http://www.rcrchive.net/rc...

Let the flame war begin!

Dan


89 Answers

dblack

3/19/2005 9:46:00 PM

0

ES

3/19/2005 9:46:00 PM

0


In data 3/19/2005, "Daniel Amelang" <daniel.amelang@gmail.com> ha
scritto:

>I know that it's not standard policy to announce RCRs on ruby-talk,
>but since this has been a topic of conversation (debate, polemic,
>death threats?) lately on this list, I thought it relevant.

Wonder what's the difference between
"I'll kill you" and "I'll kill you!"

>RCR 296: Destructive methods return self
>
>http://www.rcrchive.net/rc...
>
>Let the flame war begin!
>
>Dan

E



dblack

3/19/2005 9:49:00 PM

0

Daniel Amelang

3/19/2005 10:16:00 PM

0

Update: the RCR is now 297. Sorry, slip of the hand. I really meant
'minor edit', I swear!


On Sun, 20 Mar 2005 06:48:56 +0900, David A. Black <dblack@wobblini.net> wrote:
> On Sun, 20 Mar 2005, David A. Black wrote:
>
> > I'll try to fix them directly in the database.
>
> Actually you can do this as a minor edit, as the RCRs author. (Silly
> me, I forgot how convenient I made it :-)
>
>
> David
>
> --
> David A. Black
> dblack@wobblini.net
>
>


Daniel Amelang

3/19/2005 10:28:00 PM

0

For those interested in an alternative, I just put this up on the RCR:

Perhaps a more interesting solution would be to get rid of all
destructive methods and work on optimizing ther existing
non-destructive counterparts. Matz seems to prefer this solution.

http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-...

Unfortunately, the non-destructive versions are still quite noticeably slower.

If interest towards this approach materializes, I would be happy to
supercede this RCR.

Dan


Nikolai Weibull

3/19/2005 10:37:00 PM

0

* Daniel Amelang (Mar 19, 2005 23:30):
> Perhaps a more interesting solution would be to get rid of all
> destructive methods and work on optimizing ther existing
> non-destructive counterparts. Matz seems to prefer this solution.

> http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-...

> Unfortunately, the non-destructive versions are still quite noticeably
> slower.

No they're not. Where are you getting these assertions from?,
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);}


Daniel Amelang

3/19/2005 10:48:00 PM

0

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

I use ruby in the bioinformatics field. We deal with very long
biological sequence data and protein structures. I'll have to go
through my code and post some examples with corresponding bio data,
but I've already spent enough time today on the RCR. I may have some
examples from my computer graphics class years ago that used sort!
also. You're right for asking for benchmarks, I just have to move on
to other things right now.

So, anyone else want to brew up some examples? I'd be glad to be proved wrong.

And don't forget, unless bang(!) methods are eliminated entirely,
there is still the problem with the confusion (of experienced ruby
programmers).

Dan


dblack

3/19/2005 11:11:00 PM

0

djberg96

3/19/2005 11:58:00 PM

0

Nikolai Weibull wrote:
> * Daniel Amelang (Mar 19, 2005 23:30):
> > Perhaps a more interesting solution would be to get rid of all
> > destructive methods and work on optimizing ther existing
> > non-destructive counterparts. Matz seems to prefer this solution.
>
> > http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-...
>
> > Unfortunately, the non-destructive versions are still quite
noticeably
> > slower.
>
> No they're not. Where are you getting these assertions from?,
> nikolai

Oh, I dunno. Maybe this benchmark?

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

Here are the results of my benchmark running on a 1.8 GHz P4, 512MB
RAM, on Windows XP, SP2. The actual benchmark code I used it further
below.

C:\eclipse\workspace\ruby-foo\benchmarks>ruby bang.rb
user system total real
capitalize 1.862000 0.000000 1.862000 ( 1.923000)
capitalize! 0.591000 0.000000 0.591000 ( 0.600000)
chomp 1.663000 0.010000 1.673000 ( 1.853000)
chomp! 0.510000 0.000000 0.510000 ( 0.511000)
delete 5.739000 0.030000 5.769000 ( 6.449000)
delete! 4.396000 0.000000 4.396000 ( 4.606000)
downcase 1.712000 0.010000 1.722000 ( 2.294000)
downcase! 0.581000 0.000000 0.581000 ( 0.580000)
gsub 4.296000 0.030000 4.326000 ( 5.188000)
gsub! 0.972000 0.000000 0.972000 ( 1.161000)
lstrip 1.762000 0.020000 1.782000 ( 2.123000)
lstrip! 0.431000 0.000000 0.431000 ( 0.431000)
next 1.813000 0.000000 1.813000 ( 1.933000)
next! 1.331000 0.010000 1.341000 ( 1.472000)
reverse 1.633000 0.010000 1.643000 ( 1.742000)
reverse! 0.380000 0.000000 0.380000 ( 0.501000)
rstrip 1.773000 0.000000 1.773000 ( 1.882000)
rstrip! 0.420000 0.000000 0.420000 ( 0.431000)
slice 1.883000 0.020000 1.903000 ( 2.454000)
slice! 3.415000 0.010000 3.425000 ( 3.765000)
strip 1.793000 0.000000 1.793000 ( 1.812000)
strip! 0.370000 0.000000 0.370000 ( 0.411000)
sub 1.302000 0.000000 1.302000 ( 1.382000)
sub! 0.901000 0.000000 0.901000 ( 1.202000)
swapcase 0.862000 0.000000 0.862000 ( 0.961000)
swapcase! 0.420000 0.000000 0.420000 ( 0.451000)
tr 3.515000 0.000000 3.515000 ( 3.925000)
tr 2.284000 0.000000 2.284000 ( 2.484000)
tr_s 3.545000 0.010000 3.555000 ( 3.845000)
tr_s! 2.193000 0.000000 2.193000 ( 2.303000)
upcase 2.023000 0.000000 2.023000 ( 2.103000)
upcase! 0.631000 0.000000 0.631000 ( 0.651000)

require "benchmark"
include Benchmark

s1 = " hello "
s2 = " hello "
s3 = " hello "
max = 500000

bm do |bench|
bench.report("capitalize"){
max.times{ s1.capitalize }
}

bench.report("capitalize!"){
max.times{ s1.capitalize! }
}

bench.report("chomp"){
max.times{ s1.chomp }
}

bench.report("chomp!"){
max.times{ s1.chomp! }
}

bench.report("delete"){
max.times{ s1.delete("o") }
}

bench.report("delete!"){
max.times{ s1.delete!("o") }
}

bench.report("downcase"){
max.times{ s1.downcase }
}

bench.report("downcase!"){
max.times{ s1.downcase! }
}

bench.report("gsub"){
max.times{ s1.gsub(/e/,"i") }
}

bench.report("gsub!"){
max.times{ s1.gsub!(/e/,"i") }
}

bench.report("lstrip"){
max.times{ s1.lstrip }
}

bench.report("lstrip!"){
max.times{ s1.lstrip! }
}

bench.report("next"){
max.times{ s1.next }
}

bench.report("next!"){
max.times{ s1.next! }
}

bench.report("reverse"){
max.times{ s1.reverse }
}

bench.report("reverse!"){
max.times{ s1.reverse! }
}

bench.report("rstrip"){
max.times{ s1.rstrip }
}

bench.report("rstrip!"){
max.times{ s1.rstrip! }
}

bench.report("slice"){
max.times{ s2.slice(1..4) }
}

bench.report("slice!"){
max.times{ s2.slice!(1..4) }
}

bench.report("strip"){
max.times{ s2.strip }
}

bench.report("strip!"){
max.times{ s2.strip! }
}

bench.report("sub"){
max.times{ s2.sub(/e/,"i") }
}

bench.report("sub!"){
max.times{ s2.sub!(/e/,"i") }
}

bench.report("swapcase"){
max.times{ s2.swapcase }
}

bench.report("swapcase!"){
max.times{ s2.swapcase! }
}

bench.report("tr"){
max.times{ s3.tr("e","a") }
}

bench.report("tr"){
max.times{ s3.tr!("e","a") }
}

bench.report("tr_s"){
max.times{ s3.tr_s("a","e") }
}

bench.report("tr_s!"){
max.times{ s3.tr_s!("a","e") }
}

bench.report("upcase"){
max.times{ s3.upcase }
}

bench.report("upcase!"){
max.times{ s3.upcase! }
}
end

Regards,

Dan

Nikolai Weibull

3/20/2005 1:12:00 AM

0

* 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);}