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.


---
demerphq

    First they ignore you, then they laugh at you, then they fight you, then you win.
    -- Gandhi



In reply to Stats from a Handrolled Profiler by demerphq

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.