Deleted: xdebug/trunk/contrib/api/parser.php =================================================================== --- xdebug/trunk/contrib/api/parser.php 2010-06-06 16:52:33 UTC (rev 3295) +++ xdebug/trunk/contrib/api/parser.php 2010-06-06 17:09:19 UTC (rev 3296) @@ -1,145 +0,0 @@ -array(string, float, int). - */ - protected $stack; - - /** - * Stores per function the total time and memory increases and calls - * string=>array(float, int, int) - */ - protected $functions; - - public function __construct( $fileName ) - { - $this->handle = fopen( $fileName, 'r' ); - if ( !$this->handle ) - { - throw new Exception( "Can't open '$fileName'" ); - } - $this->stack[-1] = array( '', 0, 0, 0, 0 ); - $this->stack[ 0] = array( '', 0, 0, 0, 0 ); - } - - public function parse() - { - echo "\nparsing...\n"; - $c = 0; - $size = fstat( $this->handle ); - $size = $size['size']; - $read = 0; - - while ( !feof( $this->handle ) ) - { - $buffer = fgets( $this->handle, 4096 ); - $read += strlen( $buffer ); - $this->parseLine( $buffer ); - $c++; - - if ( $c % 25000 === 0 ) - { - printf( "%7d (%5.2f%%)\n", $c, ( $read / $size ) * 100 ); - } - } - echo "\nDone.\n\n"; - } - - private function parseLine( $line ) - { - /* - if ( preg_match( '@^Version: (.*)@', $line, $matches ) ) - { - } - else if ( preg_match( '@^File format: (.*)@', $line, $matches ) ) - { - } - else if ( preg_match( '@^TRACE.*@', $line, $matches ) ) - { - } - else // assume a normal line - */ - { - $parts = explode( "\t", $line ); - if ( count( $parts ) < 5 ) - { - return; - } - $depth = $parts[0]; - $funcNr = $parts[1]; - $time = $parts[3]; - $memory = $parts[4]; - if ( $parts[2] == '0' ) // function entry - { - $funcName = $parts[5]; - $intFunc = $parts[6]; - - $this->stack[$depth] = array( $funcName, $time, $memory, 0, 0 ); - } - else if ( $parts[2] == '1' ) // function exit - { - list( $funcName, $prevTime, $prevMem, $nestedTime, $nestedMemory ) = $this->stack[$depth]; - - // collapse data onto functions array - $dTime = $time - $prevTime; - $dMemory = $memory - $prevMem; - - $this->stack[$depth - 1][3] += $dTime; - $this->stack[$depth - 1][4] += $dMemory; - - $this->addToFunction( $funcName, $dTime, $dMemory, $nestedTime, $nestedMemory ); - } - } - } - - protected function addToFunction( $function, $time, $memory, $nestedTime, $nestedMemory ) - { - if ( !isset( $this->functions[$function] ) ) - { - $this->functions[$function] = array( 1, $time, $memory, $nestedTime, $nestedMemory ); - } - else - { - $elem = &$this->functions[$function]; - $elem[0]++; - $elem[1] += $time; - $elem[2] += $memory; - $elem[3] += $nestedTime; - $elem[4] += $nestedMemory; - } - } - - public function getFunctions( $sortKey = null ) - { - $result = array(); - foreach ( $this->functions as $name => $function ) - { - $result[$name] = array( - 'calls' => $function[0], - 'time-inclusive' => $function[1], - 'memory-inclusive' => $function[2], - 'time-children' => $function[3], - 'memory-children' => $function[4], - 'time-own' => $function[1] - $function[3], - 'memory-own' => $function[2] - $function[4] - ); - } - - if ( $sortKey !== null ) - { - uasort( $result, - function( $a, $b ) use ( $sortKey ) - { - return ( $a[$sortKey] > $b[$sortKey] ) ? -1 : ( $a[$sortKey] < $b[$sortKey] ? 1 : 0 ); - } - ); - } - - return $result; - } -} -?> Modified: xdebug/trunk/contrib/tracefile-analyser.php =================================================================== --- xdebug/trunk/contrib/tracefile-analyser.php 2010-06-06 16:52:33 UTC (rev 3295) +++ xdebug/trunk/contrib/tracefile-analyser.php 2010-06-06 17:09:19 UTC (rev 3296) @@ -1,11 +1,7 @@ 4 ) { - echo "usage:\n\tphp run-cli tracefile [sortkey] [elements]\n\n"; - echo "Allowed sortkeys:\n\tcalls, time-inclusive, memory-inclusive, time-own, memory-own\n"; - die(); + showUsage(); } $fileName = $argv[1]; @@ -14,6 +10,10 @@ if ( $argc > 2 ) { $sortKey = $argv[2]; + if ( !in_array( $sortKey, array( 'calls', 'time-inclusive', 'memory-inclusive', 'time-own', 'memory-own' ) ) ) + { + showUsage(); + } } if ( $argc > 3 ) { @@ -24,12 +24,23 @@ $o->parse(); $functions = $o->getFunctions( $sortKey ); +// find longest function name +$maxLen = 0; +foreach( $functions as $name => $f ) +{ + if ( strlen( $name ) > $maxLen ) + { + $maxLen = strlen( $name ); + } +} + echo "Showing the {$elements} most costly calls sorted by '{$sortKey}'.\n\n"; -echo " Inclusive Own\n"; -echo "function #calls time memory time memory\n"; -echo "-------------------------------------------------------------------------------\n"; +echo " ", str_repeat( ' ', $maxLen - 8 ), " Inclusive Own\n"; +echo "function", str_repeat( ' ', $maxLen - 8 ), "#calls time memory time memory\n"; +echo "--------", str_repeat( '-', $maxLen - 8 ), "----------------------------------------\n"; +// display functions $c = 0; foreach( $functions as $name => $f ) { @@ -38,9 +49,171 @@ { break; } - printf( "%-39s %5d %3.4f %8d %3.4f %8d\n", + printf( "%-{$maxLen}s %5d %3.4f %8d %3.4f %8d\n", $name, $f['calls'], $f['time-inclusive'], $f['memory-inclusive'], $f['time-own'], $f['memory-own'] ); } +function showUsage() +{ + echo "usage:\n\tphp run-cli tracefile [sortkey] [elements]\n\n"; + echo "Allowed sortkeys:\n\tcalls, time-inclusive, memory-inclusive, time-own, memory-own\n"; + die(); +} + +class drXdebugTraceFileParser +{ + protected $handle; + + /** + * Stores the last function, time and memory for the entry point per + * stack depth. int=>array(string, float, int). + */ + protected $stack; + + /** + * Stores per function the total time and memory increases and calls + * string=>array(float, int, int) + */ + protected $functions; + + /** + * Stores which functions are on the stack + */ + protected $stackFunctions; + + public function __construct( $fileName ) + { + $this->handle = fopen( $fileName, 'r' ); + if ( !$this->handle ) + { + throw new Exception( "Can't open '$fileName'" ); + } + $this->stack[-1] = array( '', 0, 0, 0, 0 ); + $this->stack[ 0] = array( '', 0, 0, 0, 0 ); + + $this->stackFunctions = array(); + } + + public function parse() + { + echo "\nparsing...\n"; + $c = 0; + $size = fstat( $this->handle ); + $size = $size['size']; + $read = 0; + + while ( !feof( $this->handle ) ) + { + $buffer = fgets( $this->handle, 4096 ); + $read += strlen( $buffer ); + $this->parseLine( $buffer ); + $c++; + + if ( $c % 25000 === 0 ) + { + printf( " (%5.2f%%)\n", ( $read / $size ) * 100 ); + } + } + echo "\nDone.\n\n"; + } + + private function parseLine( $line ) + { + /* + if ( preg_match( '@^Version: (.*)@', $line, $matches ) ) + { + } + else if ( preg_match( '@^File format: (.*)@', $line, $matches ) ) + { + } + else if ( preg_match( '@^TRACE.*@', $line, $matches ) ) + { + } + else // assume a normal line + */ + { + $parts = explode( "\t", $line ); + if ( count( $parts ) < 5 ) + { + return; + } + $depth = $parts[0]; + $funcNr = $parts[1]; + $time = $parts[3]; + $memory = $parts[4]; + if ( $parts[2] == '0' ) // function entry + { + $funcName = $parts[5]; + $intFunc = $parts[6]; + + $this->stack[$depth] = array( $funcName, $time, $memory, 0, 0 ); + + array_push( $this->stackFunctions, $funcName ); + } + else if ( $parts[2] == '1' ) // function exit + { + list( $funcName, $prevTime, $prevMem, $nestedTime, $nestedMemory ) = $this->stack[$depth]; + + // collapse data onto functions array + $dTime = $time - $prevTime; + $dMemory = $memory - $prevMem; + + $this->stack[$depth - 1][3] += $dTime; + $this->stack[$depth - 1][4] += $dMemory; + + array_pop( $this->stackFunctions ); + + $this->addToFunction( $funcName, $dTime, $dMemory, $nestedTime, $nestedMemory ); + } + } + } + + protected function addToFunction( $function, $time, $memory, $nestedTime, $nestedMemory ) + { + if ( !isset( $this->functions[$function] ) ) + { + $this->functions[$function] = array( 0, 0, 0, 0, 0 ); + } + + $elem = &$this->functions[$function]; + $elem[0]++; + if ( !in_array( $function, $this->stackFunctions ) ) { + $elem[1] += $time; + $elem[2] += $memory; + $elem[3] += $nestedTime; + $elem[4] += $nestedMemory; + } + } + + public function getFunctions( $sortKey = null ) + { + $result = array(); + foreach ( $this->functions as $name => $function ) + { + $result[$name] = array( + 'calls' => $function[0], + 'time-inclusive' => $function[1], + 'memory-inclusive' => $function[2], + 'time-children' => $function[3], + 'memory-children' => $function[4], + 'time-own' => $function[1] - $function[3], + 'memory-own' => $function[2] - $function[4] + ); + } + + if ( $sortKey !== null ) + { + uasort( $result, + function( $a, $b ) use ( $sortKey ) + { + return ( $a[$sortKey] > $b[$sortKey] ) ? -1 : ( $a[$sortKey] < $b[$sortKey] ? 1 : 0 ); + } + ); + } + + return $result; + } +} +?>