in reply to Difference between tr/// and s///?
The difference is that one translates single characters and one substitutes patterns. Which to use should depend mostly on what you are doing. If you are replacing pluses with spaces, then pick whichever you are more comfortable with or based on what direction the code is likely to evolve in.
If you foresee the code changing to s/[\s+]+/ /g one day, then starting with s/\+/ /g is probably a good idea. If you foresee the code changing to tr/+\-<>/ _()/, then starting with tr/+/ / is probably a good idea.
For these reasons, I usually prefer s/\+/ /g over tr/+/ /.
Some will make a big deal about tr/// usually being faster than s///. I make a big deal about the speed difference between tr/// and s/// usually being imperceptible. Benchmark has to do a lot of tricky things to make the difference measurable. tr/// is usually faster than s///, but not always and it almost always doesn't matter in the slightest.
Here is a benchmark to demonstrate both points:
and the output:#!/usr/bin/perl use Benchmark qw( cmpthese ); my( $count, $len )= @ARGV; $count ||= 10; $len ||= 5000; my $string= join '+', map { join '', map {('a'..'z')[rand(26)]} 0..rand($len) } 1..$count; sub subst { $string =~ s/\+/-/g; $string =~ s/\-/+/g; 0; } sub trans { $string =~ tr/\+/-/; $string =~ tr/\-/+/; 0; } cmpthese( -3, { a_s => \&subst, b_s => \&subst, a_t => \&trans, b_t => \&trans, } );
Rate b_t a_t b_s a_s b_t 8190/s -- -1% -40% -40% a_t 8258/s 1% -- -39% -40% b_s 13615/s 66% 65% -- -1% a_s 13720/s 68% 66% 1% --
So here I've got an unusually long string (50,000 bytes) and the difference in speed between the two is about 0.00005 seconds. Most of the time your strings aren't that long so the difference is even less.
Sure, there are rare cases where you are doing hundreds of thousands of these operations on really long strings and these tiny difference add up. But even in such cases, if you manage to get them to add up to a whole second or two, then all of the other overhead (which Benchmark has to work hard to subtract from the above comparisons) usually adds up to several minutes and the difference is still imperceptible.
So, in those cases you should probably be studying the algorithm you are using or profiling the code rather than running benchmarks trying to prematurely optimize nano-operations such as these. (:
Update: BTW, the reason (or at least my educated guess at the reason) that this benchmark shows s/// being faster is because tr/// looks up every character in the map that it builds while, in this case, s/// can (more quickly) skip to the next character that it cares about.
- tye
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Difference between tr// and s///? (function not speed)
by kalamiti (Friar) on Feb 07, 2004 at 07:58 UTC | |
by makar (Novice) on Feb 09, 2004 at 16:17 UTC |