Created
October 15, 2010 19:41
-
-
Save Nycto/628803 to your computer and use it in GitHub Desktop.
Revisions
-
Nycto revised this gist
Oct 15, 2010 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ * Analyzes the output of an XDebug script trace * * The original version can be found here: * http://svn.xdebug.org/cgi-bin/viewvc.cgi/xdebug/trunk/contrib/tracefile-analyser.php?root=xdebug * * This version was created to work in PHP 5.2 */ -
Nycto revised this gist
Oct 15, 2010 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,11 @@ <?php /** * Analyzes the output of an XDebug script trace * * The original version can be found here: * http://svn.xdebug.org/cgi-bin/viewvc.cgi/xdebug/trunk/contrib/tracefile-analyser.php * * This version was created to work in PHP 5.2 */ if ( $argc <= 1 || $argc > 4 ) -
Nycto revised this gist
Oct 15, 2010 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,7 @@ <?php /** * Analyzes the output of an XDebug script trace */ if ( $argc <= 1 || $argc > 4 ) { -
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,229 @@ <?php if ( $argc <= 1 || $argc > 4 ) { showUsage(); } $fileName = $argv[1]; $sortKey = 'time-own'; $elements = 25; if ( $argc > 2 ) { $sortKey = $argv[2]; if ( !in_array( $sortKey, array( 'calls', 'time-inclusive', 'memory-inclusive', 'time-own', 'memory-own' ) ) ) { showUsage(); } } if ( $argc > 3 ) { $elements = (int) $argv[3]; } $o = new drXdebugTraceFileParser( $argv[1] ); $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 " ", 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 ) { $c++; if ( $c > $elements ) { break; } 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 ) { $sort = new SortByKey($sortKey); $sort->sort($result); } return $result; } } class SortByKey { private $key; public function __construct($key) { $this->key = $key; } private function sortCallback ($a, $b) { return ( $a[$this->key] > $b[$this->key] ) ? -1 : ( $a[$this->key] < $b[$this->key] ? 1 : 0 ); } public function sort( array &$data ) { uasort($data, array($this, 'sortCallback')); } } ?>