An alternative approach to reading the first character of a string.

An alternative approach to reading the first character of a string:

$char = chr ord $string;

This is mainly of curiosity value since it would be better in terms of legibility and maintenance to use one of the more standard methods shown below. In particular substr.

Interestingly, albeit moderately, this appears to be faster than some of the other methods.

#!/usr/bin/perl -w use strict; use Benchmark 'cmpthese'; my $str = "some string here"; cmpthese( 500000, { 'pop_chord' => sub { pop_chord($str) }, '_substr' => sub { _substr($str) }, '_unpack' => sub { _unpack($str) }, '_match' => sub { _match($str) }, } ); sub pop_chord { chr ord pop } sub _substr { substr pop,0,1 } sub _unpack { unpack"a",pop } sub _match { (pop=~/(.)/s)[0] } __END__ Benchmark: timing 500000 iterations of _match, _substr, _unpack, pop_chord _match: 3 secs (3.22 usr + 0.01 sys = 3.23 CPU) @ 154798.76/s _substr: 0 secs (0.85 usr + 0.00 sys = 0.85 CPU) @ 588235.29/s _unpack: 2 secs (2.04 usr + 0.00 sys = 2.04 CPU) @ 245098.04/s pop_chord: 1 secs (0.73 usr + 0.00 sys = 0.73 CPU) @ 684931.51/s Rate _match _unpack _substr pop_chord _match 154799/s -- -37% -74% -77% _unpack 245098/s 58% -- -58% -64% _substr 588235/s 280% 140% -- -14% pop_chord 684932/s 342% 179% 16% --

Replies are listed 'Best First'.
Re: Read the first character of a string
by blakem (Monsignor) on Feb 24, 2003 at 00:06 UTC
    Interesting.... and its nearly as fast as inlining it in C.
    #!/usr/bin/perl -w use strict; use Benchmark 'cmpthese'; my $str = "some string here"; die unless (pop_chord($str) . inlined($str) . _substr($str) . _unpack($str) . _match($str) eq substr($str,0,1)x5); cmpthese( 500000, { 'pop_chord' => sub { pop_chord($str) }, 'inlined' => sub { inlined($str) }, '_substr' => sub { _substr($str) }, '_unpack' => sub { _unpack($str) }, '_match' => sub { _match($str) }, } ); sub pop_chord { chr ord pop } sub _substr { substr pop,0,1 } sub _unpack { unpack"a",pop } sub _match { (pop=~/(.)/s)[0] } use Inline C => <<'END_OF_C_CODE'; char inlined(char* str) { return str[0]; } END_OF_C_CODE __END__ Benchmark: timing 500000 iterations of _match, _substr, _unpack, inl +ined, pop_chord... _match: 3 wallclock secs ( 3.98 usr + 0.00 sys = 3.98 CPU) @ 12 +5628.14/s (n=500000) _substr: 2 wallclock secs ( 1.45 usr + 0.00 sys = 1.45 CPU) @ 34 +4827.59/s (n=500000) _unpack: 4 wallclock secs ( 2.68 usr + 0.00 sys = 2.68 CPU) @ 18 +6567.16/s (n=500000) inlined: 1 wallclock secs ( 0.58 usr + 0.00 sys = 0.58 CPU) @ 86 +2068.97/s (n=500000) pop_chord: 1 wallclock secs ( 1.30 usr + 0.00 sys = 1.30 CPU) @ 38 +4615.38/s (n=500000) Rate _match _unpack _substr pop_chord inlined _match 125628/s -- -33% -64% -67% -85% _unpack 186567/s 49% -- -46% -51% -78% _substr 344828/s 174% 85% -- -10% -60% pop_chord 384615/s 206% 106% 12% -- -55% inlined 862069/s 586% 362% 150% 124% --

    -Blake