Wondering if perl4 would run one of my RegExp-happy scripts faster than perl5 I had to roll my own chr() and thought I'd benchmark it against the builtin.

I was surprised to see that the chr() builtin was significantly slower than pack("C"). Even more surprised that the sub mychr was faster than the direct pack("C"). Can anyone explain why either of these is the case?

% perl5.8.0 use Benchmark; sub mychr { return pack("C", shift); } @array = @array = (0 .. 255) x 100; timethese(1000, { 'sub' => 'foreach (@array) { my $chr = chr($_) }', 'builtin' => 'foreach (@array) { my $chr = &mychr($_) }', 'direct' => 'foreach (@array) { my $chr = pack("C", $_) }', }); Benchmark: timing 1000 iterations of builtin, direct, sub... builtin: 156 wallclock secs (143.82 usr + 0.17 sys = 143.99 CPU) @ + 6.94/s (n=1000) direct: 53 wallclock secs (48.89 usr + 0.04 sys = 48.93 CPU) @ 20 +.44/s (n=1000) sub: 37 wallclock secs (31.16 usr + 0.03 sys = 31.19 CPU) @ 32 +.06/s (n=1000)

Replies are listed 'Best First'.
Re: chr() suprisingly slow
by Abigail-II (Bishop) on Jul 30, 2002 at 14:21 UTC
    What do you mean, sub mychr was faster? You are confusing yourself by mislabeling your cases. The "mychr" is labelled "builtin", and clocks 6.94 iterations per second, well below the 20.44 from using 'pack' and the 32.06 from using chr.

    I would say that chr wins over pack, with the sub coming in well last.

    Abigail

      Thanks. I knew something was wrong but however much I looked at I just couldn't see what.

      I feel like a complete melon now. :-)

Re: chr() suprisingly slow
by demerphq (Chancellor) on Jul 30, 2002 at 14:39 UTC
    Er. I think you have made a mistake in your benchmarking. You swapped the labels for the code used for the "sub" and "builtin".

    I fixed the benchmark and under perl 5.6.1 get the results one would expect:

    use Benchmark 'cmpthese'; sub mychr { return pack("C", shift); } @array = (0 .. 255) x 100; cmpthese(-2, { 'builtin' => 'foreach (@array) { my $chr = chr($_) }', 'sub' => 'foreach (@array) { my $chr = &mychr($_) }', 'pack' => 'foreach (@array) { my $chr = pack("C", $_) }', }); __END__ Benchmark: running builtin, pack, sub, each for at least 2 CPU seconds +... builtin: 2 wallclock secs ( 2.06 usr + 0.00 sys = 2.06 CPU) @ 36 +.84/s (n=76) pack: 2 wallclock secs ( 2.11 usr + 0.00 sys = 2.11 CPU) @ 27 +.03/s (n=57) sub: 2 wallclock secs ( 2.06 usr + 0.00 sys = 2.06 CPU) @ 8 +.24/s (n=17) Rate sub pack builtin sub 8.24/s -- -70% -78% pack 27.0/s 228% -- -27% builtin 36.8/s 347% 36% --
    Cheers,

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.