http://www.perlmonks.org?node_id=289772


in reply to Check whether your hash keys have random order

Why launch a separate process?
use Config; my $ccflags = $Config{ccflags}; ...
No need to fork for this!

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

Replies are listed 'Best First'.
Re: •Re: Check whether your hash keys have random order
by liz (Monsignor) on Sep 08, 2003 at 16:31 UTC
    I was trying to save memory by not having to load Config.pm. But because of your remark, I decided to do a Benchmark:
    Benchmark: timing 1000 iterations of open, use...
     open: 38 wallclock secs ( 2.62 usr  0.00 sys + 16.14 cusr 12.96 csys = 31.72 CPU) @ 381.68/s (n=1000)
      use: 14 wallclock secs (13.15 usr +  0.00 sys = 13.15 CPU) @ 76.05/s (n=1000)
    

    This surprised me a lot!. The fork() approach with open() seems to be 5 times as fast as loading Config.pm!

    Alas, I think I stumbled upon a bug / feature / problem of Benchmark: apparently, only "usr" CPU is taken into account when calculating the number of runs/second, and the "usr" CPU is of course a lot less than with fork/open than it is with use.

    Still, the fork/open approach only takes 2.5 times as much CPU as loading Config.pm. I wonder if that is a testament of the efficiency of fork(), or the slowness of Config.pm. ;-)

    The code:

    use Benchmark; timethese( 1000, { open => sub { open my $handle, $^X.' -V:ccflags |'; my $ccflags = <$handle>; delete $INC{'Config.pm'}; }, use => sub { require Config; Config->import; my $ccflags = $Config{ccflags}; delete $INC{'Config.pm'}; }, } );

    Liz

      The use version creates a tied perl hash, employing caching ... while the other version doesn't bother to do that and simply matches on a scalar.
      perl -d:Trace -V:ccflags >> Config.pm:1012: foreach(@_){ >> Config.pm:1013: config_re($_), next if /\W/; >> Config.pm:1014: my $v=(exists $Config{$_}) ? $Config{$_} : 'UNKNOW +N'; >> Config.pm:988: exists($_[0]->{$_[1]}) or >> Config.pm:882: return $_[0]->{$_[1]} if (exists $_[0]->{$_[1]}) +; >> Config.pm:885: my($value, $start, $marker, $quote_type); >> Config.pm:887: $quote_type = "'"; >> Config.pm:889: if ($_[1] eq 'byteorder') { >> Config.pm:929: $marker = "$_[1]="; >> Config.pm:932: $start = index($config_sh, "\n$marker$quote_type") +; >> Config.pm:934: if ($start == -1) { >> Config.pm:938: return undef if ( ($start == -1) && # in case it' +s first >> Config.pm:940: if ($start == -1) { >> Config.pm:947: $start += length($marker) + 2; >> Config.pm:949: $value = substr($config_sh, $start, >> Config.pm:956: if ($quote_type eq '"') { >> Config.pm:963: $value = undef if $value eq 'undef'; >> Config.pm:964: $_[0]->{$_[1]} = $value; # cache it >> Config.pm:965: return $value; >> Config.pm:1015: $v='undef' unless defined $v; >> Config.pm:1016: print "$_='$v';\n"; ccflags='-nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAV +E_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -D PERL_MSVCRT_READFIX'; >> Config.pm:1012: foreach(@_){
      Maybe i'm wrong ...