demerphq has asked for the wisdom of the Perl Monks concerning the following question:
I wanted to profile some stuff today, so i tried out Devel::Dprof and Devel::Profiler. Unfortunately both have heart attacks with various things that I do in my script so I got nowhere. Fortunately i remembered that you can hand roll your own relatively easily. I came up with the following:
{ package DB; use B; BEGIN { my $PROFILE="$0.profile"; open PROFILE,">",$PROFILE or die "$PROFILE:$!"; } sub DB {} my %skip=(); our $depth=0; sub sub { my $name=$sub; if (ref $name) { my $Bobj = B::svref_2object($sub); $name=$Bobj->GV->NAME(); } $name=~s/^main::/::/; if ( $skip{$name} or $name=~/^[a-z]+(::|$)/ or $name=~/^__ANON +__/ ) { return &$sub; } my @time=(time,times); print PROFILE "> ",(" " x $depth),$name,"\n"; my (@array,$scalar); { local $depth=$depth+1; if (wantarray) { @array=&$sub; } elsif (defined wantarray) { $scalar=&$sub; } else { &$sub; } } my @after=(time,times); my $time=join(", ",map {$after[$_]-$time[$_] } 0..$#time); print PROFILE "< ",(" " x $depth),$name,"=$time","\n"; if (wantarray) { return @array } elsif (defined wantarray) { return $scalar } } } 1
Which produces output like:
E:\>perl -I./lib -d:MyDB -e "sub X { Y() } sub Y { sleep(1) } X,X,Y" E:\>type -e.profile > ::X > ::Y < ::Y=1, 0, 0, 0, 0 < ::X=1, 0, 0, 0, 0 > ::X > ::Y < ::Y=1, 0, 0, 0, 0 < ::X=1, 0, 0, 0, 0 > ::Y < ::Y=1, 0, 0, 0, 0
The following is a larger but better example.
> Rating::CachedObject::new > Rating::ZoneTimePlan::init > Rating::DBI::dbh < Rating::DBI::dbh=0, 0, 0, 0, 0 > DBI::db::selectall_arrayref > DBI::db::prepare > DBD::Sybase::db::prepare > DBI::_new_sth > DBI::_new_handle > DBI::st::TIEHASH < DBI::st::TIEHASH=0, 0, 0, 0, 0 > DBI::_setup_handle < DBI::_setup_handle=0, 0.0150000000000006, 0, 0, 0 < DBI::_new_handle=0, 0.0150000000000006, 0, 0, 0 < DBI::_new_sth=0, 0.0150000000000006, 0, 0, 0 > DBD::Sybase::st::_prepare < DBD::Sybase::st::_prepare=0, 0, 0, 0, 0 < DBD::Sybase::db::prepare=0, 0.0150000000000006, 0, 0, 0 < DBI::db::prepare=0, 0.0150000000000006, 0, 0, 0 > DBI::st::DESTROY < DBI::st::DESTROY=0, 0, 0, 0, 0 > DBI::st::DESTROY < DBI::st::DESTROY=0, 0, 0, 0, 0 > DBD::_mem::common::DESTROY < DBD::_mem::common::DESTROY=0, 0, 0, 0, 0 < DBI::db::selectall_arrayref=0, 0.0150000000000006, 0, 0, 0 > Rating::CachedObject::new < Rating::CachedObject::new=0, 0, 0, 0, 0 < Rating::ZoneTimePlan::init=0, 0.0150000000000006, 0, 0, 0 < Rating::CachedObject::new=0, 0.0150000000000006, 0, 0, 0
The problem is I cant really think of too many ways to aggregate this information usefully. Any ideas from you folks would be very welcome.
Cheers.
First they ignore you, then they laugh at you, then they fight you, then you win.
-- Gandhi
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Stats from a Handrolled Profiler
by tye (Sage) on Aug 27, 2004 at 03:47 UTC | |
by demerphq (Chancellor) on Sep 03, 2004 at 15:27 UTC |