Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add options: verbose, exclude_endstats_modules; add todo; mark v0.02

  • Loading branch information...
commit cc9453eb9072935dc70f9fd0618b6d9c6268ce4b 1 parent 6d637e2
Steven Haryanto (on Asus EEEPC) authored
Showing with 125 additions and 12 deletions.
  1. +7 −0 Changes
  2. +2 −1  dist.ini
  3. +116 −11 lib/Devel/EndStats.pm
View
7 Changes
@@ -1,5 +1,12 @@
Revision history for Devel-EndStats
+0.02 2010-07-28
+
+ Require Perl 5.10.
+
+ Add options: verbose, exclude_endstats_modules.
+
+
0.01 2010-07-28
First release.
View
3  dist.ini
@@ -1,5 +1,5 @@
name = Devel-EndStats
-version = 0.01
+version = 0.02
author = Steven Haryanto <stevenharyanto@gmail.com>
license = Perl_5
copyright_holder = Steven Haryanto
@@ -25,3 +25,4 @@ remove = MakeMaker
; for testing
; for runtime
+perl = 5.010000
View
127 lib/Devel/EndStats.pm
@@ -3,7 +3,8 @@ package Devel::EndStats;
=head1 SYNOPSIS
- perl -MDevel::EndStats script.pl
+ # from the command line
+ % perl -MDevel::EndStats script.pl
=head1 DESCRIPTION
@@ -16,28 +17,122 @@ Some notes/caveats:
END blocks declared after Devel::EndStats' will be executed after it, so in that
case it's ideal to load Devel::EndStats as the last module.
-In total number of modules loaded, Devel::EndStats itself is excluded.
+In modules statistics, Devel::EndStats excludes itself and the modules it uses.
+Devel::EndStats tries to check whether those modules are actually loaded/used by
+your program instead of just by Devel::EndStats and if so, will not exclude them.
=cut
-# deliberately not using warnings, strict, or other modules
+use 5.010;
+
+sub _inc2modname {
+ local $_ = shift;
+ s!/!::!g;
+ s/\.pm$//;
+ $_;
+}
+
+sub _mod2incname {
+ local $_ = shift;
+ s!::!/!g;
+ "$_.pm";
+}
+
+my @my_modules = qw(
+ );
+
+my %excluded_modules;
+
+my %opts = (
+ verbose => 0,
+ exclude_endstats_modules => 1,
+);
+
+=head1 OPTIONS
+
+Some options are accepted. They can be passed via the B<use> statement:
+
+ # from the command line
+ % perl -MDevel::EndStats=verbose,1 script.pl
+
+ # from script
+ use Devel::EndStats verbose=>1;
+
+or via the DEVELENDSTATS_OPTS environment variable:
+
+ % DEVELENDSTATS_OPTS='verbose=1' perl -MDevel::EndStats script.pl
+
+=over 4
+
+=item * verbose => BOOL
+
+Can also be set via VERBOSE environment variable. If set to true, display more
+statistics (like per-module statistics). Default is 0.
+
+=item * exclude_endstats_modules => BOOL
+
+If set to true, exclude Devel::EndStats itself and the modules it uses from the
+statistics. Default is 1.
+
+=back
+
+=cut
+
+sub import {
+ my ($class, %args) = @_;
+ $opts{verbose} = $ENV{VERBOSE} if defined($ENV{VERBOSE});
+ if ($ENV{DEVELENDSTATS_OPTS}) {
+ while ($ENV{DEVELENDSTATS_OPTS} =~ /(\w+)=(\S+)/g) {
+ $opts{$1} = $2;
+ }
+ }
+ $opts{$_} = $args{$_} for keys %args;
+}
+
+INIT {
+ for (qw(feature Devel::EndStats)) {
+ $excluded_modules{ _mod2incname($_) }++
+ if $opts{exclude_endstats_modules};
+ }
+
+ # load our modules and exclude it from stats
+ for my $m (@my_modules) {
+ my $im = _mod2incname($m);
+ next if $INC{$im};
+ my %INC0 = %INC;
+ require $im;
+ if ($opts{exclude_endstats_modules}) {
+ for (keys %INC) {
+ $excluded_modules{$_}++ unless $INC0{$_};
+ }
+ }
+ }
+}
END {
print "# BEGIN stats from Devel::EndStats\n";
printf "# Program runtime duration (s): %d\n", (time() - $^T);
- #use Data::Dump; dd %INC;
- printf "# Total number of module files loaded: %d\n", scalar(keys %INC)-1;
-
+ my $modules = 0;
my $lines = 0;
+ my %lines;
local *F;
- for (keys %INC) {
- next if m!^(Devel/EndStats)\.pm$!;
- open F, $INC{$_} or next;
- $lines++ while <F>;
+ for my $im (keys %INC) {
+ next if $excluded_modules{$im};
+ $modules++;
+ $lines{$im} = 0;
+ next unless $INC{$im}; # undefined in some cases
+ open F, $INC{$im} or next;
+ while (<F>) { $lines++; $lines{$im}++ }
}
+ printf "# Total number of module files loaded: %d\n", $modules;
printf "# Total number of modules lines loaded: %d\n", $lines;
+ if ($opts{verbose}) {
+ for my $im (sort {$lines{$b} <=> $lines{$a}} keys %lines) {
+ printf "# Lines from %s: %d\n", _inc2modname($im), $lines{$im};
+ }
+ }
print "# END stats\n";
}
@@ -47,7 +142,7 @@ END {
=head2 What is the purpose of this module?
This module might be useful during development. I first wrote this module when
-trying to reduce startup overhead of a command-line application, by looking at
+trying to reduce startup overhead of a command line application, by looking at
how many modules the app has loaded and try to avoid loading modules whenever
it's unnecessary.
@@ -57,6 +152,16 @@ Sure, if it's useful. As they say, (comments|patches) are welcome.
=head1 SEE ALSO
+=head1 TODO
+
+* Stat: memory usage.
+* Subsecond program duration.
+* Stat: system/user time.
+* Stat: number of open files (sockets).
+* Stat: number of child processes.
+* Stat: number of XS vs PP modules.
+* Feature: remember last run's stats, compare with current run.
+
=cut
1;
Please sign in to comment.
Something went wrong with that request. Please try again.