Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^3: "require Carp" may be hazardous to your code (assume)

by tye (Sage)
on Dec 05, 2006 at 19:12 UTC ( [id://587952]=note: print w/replies, xml ) Need Help??


in reply to Re^2: "require Carp" may be hazardous to your code
in thread "require Carp" may be hazardous to your code

There's really no reason to do this. Carp is a lightweight module.

Although the proponent(s) of this practice have yet to post data to back it up where I recall having seen it, I don't recall you having posted data to support your claim either. Note that this practice predates the following in Carp.pm:

require Carp::Heavy unless $INC{"Carp/Heavy.pm"};

Note that I get quite a kick out of the last half of that statement. I'm sure the very first thing that require does is exactly that anyway, so I'd never add such trivial code in an obvious attempt at micro-optimization. But perhaps this whole hubbabaloo is just micro-optimization. (Update: Which brings up my long-standing catch phrase, "Nothing is obvious unless you are overlooking something" -- see ikegami's reply below.)

It is my belief that more than just unfounded attempts are micro-optimization were required to motivate so much reworking of these modules. I could certainly be wrong in that belief, but your say-so isn't enough to convince me otherwise.

Also note that I delay loading Carp.pm for my own reasons that I find few people share. I don't load modules that I likely don't need because I don't like my modules failing in those rare environments when some module that most people presume that everyone has is actually missing. I've certainly run into such environments many times. In fact, checking my soon-to-be-released module, the code I wrote is actually:

BEGIN { my $croak; sub _croak { if( ! $croak ) { if( eval { require Carp; 1 } ) { $croak= \&Carp::croak; } else { $croak= sub { die @_; }; } } return $croak; } }

Which means that my module works fine even if Carp.pm is nowhere to be found.

Update: I also get a kick out of the fact that most of the code has been moved out of Carp.pm and yet "require Carp" has to read over a ton of POD in order to get to that small bit of code. I'd micro-optimize that as well and move the POD after __END__. (:

- tye        

Replies are listed 'Best First'.
Re^4: "require Carp" may be hazardous to your code (assume)
by ikegami (Patriarch) on Dec 05, 2006 at 19:20 UTC

    Note that I kick quite a kick out of the last half of that statement. I'm sure the very first thing that require does is exactly that anyway, so I'd never add such trivial code in an obvious attempt at micro-optimization.

    Did you read the comment next to "require Carp::Heavy unless $INC{"Carp/Heavy.pm"};" in the source? It's not an optimization. It's done that way so the module runs when Safe disallows require.

    Update:

    I don't recall you having posted data to support your claim either.

    ( On average, it takes me 4.24 ns to load Carp. Oops, Time::HiRes loads Carp. New benchmarks in progress. )

    >perl -MTime::HiRes=time -le "$t1=time; require Carp; $t2=time; print +$t2-$t1" 4.05311584472656e-006 >perl -MTime::HiRes=time -le "$t1=time; require Carp; $t2=time; print +$t2-$t1" 4.05311584472656e-006 >perl -MTime::HiRes=time -le "$t1=time; require Carp; $t2=time; print +$t2-$t1" 4.05311584472656e-006 >perl -MTime::HiRes=time -le "$t1=time; require Carp; $t2=time; print +$t2-$t1" 5.00679016113281e-006 >perl -MTime::HiRes=time -le "$t1=time; require Carp; $t2=time; print +$t2-$t1" 4.05311584472656e-006

      Congratulations on your broken benchmark:

      > perl -MTime::HiRes -le"print $INC{'Carp.pm'}" .../Carp.pm

      Note that you also didn't address that this practice predates the factorying out of the "heavy" parts.

      - tye        

        Nice catch. I thought it was a bit fast...

        Without heavy bits: 1.34 ms

        >perl -le "$t1=time; for (1..$ARGV[0]) { delete $INC{'Carp.pm'}; requi +re Carp; } $t2=time; print(($t2-$t1)/$ARGV[0])" 100000 0.00134 >perl -le "$t1=time; for (1..$ARGV[0]) { delete $INC{'Carp.pm'}; requi +re Carp; } $t2=time; print(($t2-$t1)/$ARGV[0])" 100000 0.00134 >perl -le "$t1=time; for (1..$ARGV[0]) { delete $INC{'Carp.pm'}; requi +re Carp; } $t2=time; print(($t2-$t1)/$ARGV[0])" 100000 0.00134

        With heavy bits: 4.75 ms

        >perl -le "$t1=time; for (1..$ARGV[0]) { delete $INC{'Carp.pm'}; delet +e $INC{'Carp/Heavy.pm'}; require Carp; require Carp::Heavy; } $t2=tim +e; print(($t2-$t1)/$ARGV[0])" 100000 0.00475 >perl -le "$t1=time; for (1..$ARGV[0]) { delete $INC{'Carp.pm'}; delet +e $INC{'Carp/Heavy.pm'}; require Carp; require Carp::Heavy; } $t2=tim +e; print(($t2-$t1)/$ARGV[0])" 100000 0.00474

      Using much more lightweight code (for a FreeBSD system), I get around 30 milliseconds when not loading Carp, and 90 msecs when I do. Here is the code I used:

      use Carp; # comment this line out, or not use BSD::Process; my $t = BSD::Process->new->elapsed_time; print $t, $/; # time in milliseconds

      The times are very erratic. It seems to boil down to whether the process executes within one timeslice of the processor or not: there are definite quanta to the amount of time taken. Nevertheless, sometimes people may care about 0.06 seconds of startup time (certainly less non-negligible than 4 usec).

      • another intruder with the mooring in the heart of the Perl

Re^4: "require Carp" may be hazardous to your code (assume)
by Anonymous Monk on Dec 06, 2006 at 07:44 UTC
    because I don't like my modules failing in those rare environments when some module that most people presume that everyone has is actually missing.
    You mean when core modules are missing?

      Yes, even core modules. This Linux box in front of me has 18 top-level core modules while a "better" install has 64 of those. And I actually added a few of those 18 "by hand", which was trickier than some might expect and I abandoned adding some others because it was just too much work. And I've seen more than one Perl installation that had even fewer than that.

      And I got DBI/DBD working on the above Linux box after working around some of many authors' rash assumptions about what modules are always going to be available. Many of those work-arounds were trivial to code (the amount of functionality they were depending on from the module was trivial -- and yet they just die if it isn't there) but finding them all was a big pain.

      Yes, I realize I'm unusual in even acknowledging that such sub-core installations of Perl exist in the world, much less in doing a tiny bit of extra coding in some cases to work around missing modules when it is easy.

      - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://587952]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-19 07:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found