in reply to Re: Concatenation ... Strings
in thread Changing a character in the middle of a word (was: Concatenation ... Strings)

Just because there is more than one way to do it, doesn't make them all equal. I could also add the following to the list:

$char = chop $string while length $string > 4;

But, that may not be a good way to do it, although it is One More Way To Do It :)

#!/usr/bin/perl -w use Benchmark; $string = "hello world I am a string of some sort of length"; timethese(150_000, { "match" => sub { ($char) = $string =~ /^.{4}(.)/;}, "unpack" => sub { ($char) = unpack("x4 A1", $string);}, "substr" => sub { ($char) = substr($string,4,1);}, "silly" => sub { local $string; $char = chop $string while length + $string > 4;}, });

I consistently get results like so:

Benchmark: timing 150000 iterations of match, silly, substr, unpack... match: 4 wallclock secs ( 2.78 usr + 0.01 sys = 2.79 CPU) @ 53 +763.44/s (n=150000) silly: -1 wallclock secs ( 0.26 usr + -0.10 sys = 0.16 CPU) @ 93 +7500.00/s (n=150000) (warning: too few iterations for a reliable count) substr: 0 wallclock secs ( 0.48 usr + 0.00 sys = 0.48 CPU) @ 31 +2500.00/s (n=150000) unpack: 2 wallclock secs ( 1.41 usr + 0.11 sys = 1.52 CPU) @ 98 +684.21/s (n=150000)

Cheers,
KM

Replies are listed 'Best First'.
Re:{3} Concatenation ... Strings
by jeroenes (Priest) on Apr 12, 2001 at 11:19 UTC
    I'm afraid your benchmark left room for improvement, KM:
    use Benchmark; $string = "hello world I am a string of some sort of length" +; timethese(-1, { "match" => sub { ($char) = $string =~ /^.{4}(.)/;}, "unpack" => sub { ($char) = unpack("x4 A1", $string);}, "substr" => sub { ($char) = substr($string,4,1);}, "silly" => sub { my $string2 = $string; $char = chop $s +tring2 while length $string2 >= 4;}, #note the local });
    Which gave somewhat more expected results:
    Benchmark: running match, silly, substr, unpack, each for at least 1 C +PU seconds... match: 3 wallclock secs ( 1.00 usr + 0.02 sys = 1.02 CPU) @ 18 +0382.35/s (n=183990) silly: 4 wallclock secs ( 1.15 usr + 0.09 sys = 1.24 CPU) @ 17 +341.13/s (n=21503) substr: 2 wallclock secs ( 1.00 usr + 0.05 sys = 1.05 CPU) @ 94 +4029.52/s (n=991231) unpack: 2 wallclock secs ( 1.02 usr + 0.06 sys = 1.08 CPU) @ 36 +2192.59/s (n=391168)
    Nevertheless, I'm suprised at the speed of silly. Can anybody explain why eating that string is faster than unpack, even if the string has some length?

    Cheers,

    jeroen
    "We are not alone"(FZ)
    Update: Ouch! Fixed... silly is the slowest, and the universe is back to normal :-)
    The last benchmarks were recorded when my CPU hit a load of 4.63, so they may be a little distorted ;-)

      You 'improved' it to show basically the same results :) Let's not only do the same thing a dozen ways, let's also benchmark a dozen ways! I was somewhat surprised that the 'silly' one came up faster. Maybe in some cases chop() has a worth.

      Cheers,
      KM