[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

destructive! operations

Navindra Umanee

2/20/2005 8:23:00 AM

Hi,

Is it more efficient to use the destructive versions of functions in
Ruby? I know that in Lisp/Scheme destructive counterparts are usually
offered for efficiency reasons.

Can I assume that string.gsub! is preferable to string.gsub when I
know that the side-effect won't be affecting any other code?

I find the Ruby destructive operations sometimes inconvenient to use.
For example strip! might return null where strip would return a
string. However, if it's more efficient, I'd rather use the
destructive version.

Thanks,
Navin.


58 Answers

Yukihiro Matsumoto

2/20/2005 2:25:00 PM

0

Hi

In message "Re: destructive! operations"
on Sun, 20 Feb 2005 17:22:34 +0900, Navindra Umanee <navindra@cs.mcgill.ca> writes:

|Is it more efficient to use the destructive versions of functions in
|Ruby? I know that in Lisp/Scheme destructive counterparts are usually
|offered for efficiency reasons.
|
|Can I assume that string.gsub! is preferable to string.gsub when I
|know that the side-effect won't be affecting any other code?

Although most (not all) of bang methods are more efficient than their
counterparts, I discourage the use of them unless the performance is
really problem. "Premature optimization is the source of all evil".

matz.


Robert Klemme

2/20/2005 3:00:00 PM

0


"Yukihiro Matsumoto" <matz@ruby-lang.org> schrieb im Newsbeitrag
news:1108909479.514053.4734.nullmailer@x31.priv.netlab.jp...
> Hi
>
> In message "Re: destructive! operations"
> on Sun, 20 Feb 2005 17:22:34 +0900, Navindra Umanee
> <navindra@cs.mcgill.ca> writes:
>
> |Is it more efficient to use the destructive versions of functions in
> |Ruby? I know that in Lisp/Scheme destructive counterparts are usually
> |offered for efficiency reasons.
> |
> |Can I assume that string.gsub! is preferable to string.gsub when I
> |know that the side-effect won't be affecting any other code?
>
> Although most (not all) of bang methods are more efficient than their
> counterparts, I discourage the use of them unless the performance is
> really problem. "Premature optimization is the source of all evil".

Although I agree to the latter statement, I beg to differ on the general
remark - at least a bit. I often use this

while ( line = gets )
line.chomp!
# work with line
end

because I know it's going to be potentially invoked often - even in scripts
that are likely to run only on small input files. But for large files where
not every line is processed it easily divides the number of instances
created by a factor of 2.

Kind regards

robert

Caio Tiago Oliveira

2/20/2005 4:24:00 PM

0

Robert Klemme, 20/2/2005 12:04:
> "Yukihiro Matsumoto" <matz@ruby-lang.org> schrieb im Newsbeitrag
> news:1108909479.514053.4734.nullmailer@x31.priv.netlab.jp...
>> In message "Re: destructive! operations"
>> on Sun, 20 Feb 2005 17:22:34 +0900, Navindra Umanee
>> <navindra@cs.mcgill.ca> writes:
>>
>> |Is it more efficient to use the destructive versions of functions in
>> |Ruby? I know that in Lisp/Scheme destructive counterparts are usually
>> |offered for efficiency reasons.
>> |
>> |Can I assume that string.gsub! is preferable to string.gsub when I
>> |know that the side-effect won't be affecting any other code?
>>
>> Although most (not all) of bang methods are more efficient than their
>> counterparts, I discourage the use of them unless the performance is
>> really problem. "Premature optimization is the source of all evil".
>
>
> Although I agree to the latter statement, I beg to differ on the general
> remark - at least a bit. I often use this
>
> while ( line = gets )
> line.chomp!
> # work with line
> end
>
> because I know it's going to be potentially invoked often - even in
> scripts that are likely to run only on small input files. But for large
> files where not every line is processed it easily divides the number of
> instances created by a factor of 2.

Bad example:

while ( line = gets.chomp )
# work with line
end



Alexander Kellett

2/20/2005 4:54:00 PM

0

On Feb 20, 2005, at 5:23 PM, Caio Tiago Oliveira wrote:
> Bad example:
>
> while ( line = gets.chomp )
> # work with line
> end

unless ruby cow's the string and
the copy just has a truncating length,
then this requires copying of the line.

Alex



James Gray

2/20/2005 5:17:00 PM

0

On Feb 20, 2005, at 10:23 AM, Caio Tiago Oliveira wrote:

> Bad example:
>
> while ( line = gets.chomp )
> # work with line
> end

gets() returns a String or nil. nil does not support chomp(). When
the chomp() is inside the while loop, this isn't an issue.

James Edward Gray II



Navindra Umanee

2/20/2005 9:08:00 PM

0

James Edward Gray II <james@grayproductions.net> wrote:
> > Bad example:
> >
> > while ( line = gets.chomp )
> > # work with line
> > end
>
> gets() returns a String or nil. nil does not support chomp(). When
> the chomp() is inside the while loop, this isn't an issue.

Often think it would be nice if "" and 0 were treated like nil. Such
functions could then return "". Heck, NilClass.to_s and NilClass.to_i
already return "" and 0 respectively.

Matz talks about premature optimizations. It looks like nil was made
this way for efficiency purposes! Can't say if it was premature
though. :-)

Thanks for the answers!

Cheers,
Navin.



Navindra Umanee

2/20/2005 9:11:00 PM

0

Navindra Umanee <navindra@cs.mcgill.ca> wrote:
> Often think it would be nice if "" and 0 were treated like nil. Such
> functions could then return "". Heck, NilClass.to_s and NilClass.to_i
> already return "" and 0 respectively.

"false" too..

Incidentally I tried to make "", 0 and false respond positively to
nil?. While they did, none of the boolean tests looked at nil? to
make their decision. I guess that's the optimized part.

Cheers,
Navin.


mark sparshatt

2/20/2005 9:49:00 PM

0

Navindra Umanee wrote:
> James Edward Gray II <james@grayproductions.net> wrote:
>
>>>Bad example:
>>>
>>>while ( line = gets.chomp )
>>> # work with line
>>>end
>>
>>gets() returns a String or nil. nil does not support chomp(). When
>>the chomp() is inside the while loop, this isn't an issue.
>
>
> Often think it would be nice if "" and 0 were treated like nil. Such
> functions could then return "".

One problem with this suggestion that comes to mind is, what if there
are any blank lines in the file. then gets.chomp would return "" which
would cause the while loop to exit. Probably not what you want

--
Mark Sparshatt



Navindra Umanee

2/20/2005 10:06:00 PM

0

mark sparshatt <msparshatt@yahoo.co.uk> wrote:
> One problem with this suggestion that comes to mind is, what if there
> are any blank lines in the file. then gets.chomp would return "" which
> would cause the while loop to exit. Probably not what you want

Point. The chomp would make it not work here. There are many
situations where it could be elegant though.

Cheers,
Navin.



Csaba Henk

2/20/2005 11:36:00 PM

0

On 2005-02-20, Navindra Umanee <navindra@cs.mcgill.ca> wrote:
> Often think it would be nice if "" and 0 were treated like nil. Such
> functions could then return "". Heck, NilClass.to_s and NilClass.to_i
> already return "" and 0 respectively.

Now, only false and nil drop you to the "else" branch of a conditional.
Certainly, there are cases when it' not the best behaviour, and you
have to write extra code to get the proper control flow when you test
against 0 and/or "".

If it were the other way around, and "", 0 (and [], {}) would lead to
the "else" branch as well, again, there would occur situations when it's
not the best behaviour and you'd need to write extra code to get things
right.

Now the question is: which of the two behaviours is the right thing more
often?

My experience is that the present way is the more optimal.

It's more cleaner as well. There is no intrinsic difference between ""
and "a", 0 and 1, [] and [1]. It would be artificial to force an
instance-sensitive policy when testing agains Strings, Integers and
Arrays.

Those guys who make a difference when using them in a conditional are
clearly separated into their respective cages (I mean, classes). That's
nice...

Csaba