public function getFunctionStats()
 {
     $metrics = $this->xhprof->getCompleteMetrics();
     $profile = array();
     $main = null;
     // units in ms
     foreach ($metrics as $fname => $stats) {
         if ($this->shouldExclude($fname)) {
             continue;
         }
         // Convert elapsed times from μs to ms to match interface
         $entry = array('name' => $fname, 'calls' => $stats['ct'], 'real' => $stats['wt']['total'] / 1000, '%real' => $stats['wt']['percent'], 'cpu' => isset($stats['cpu']) ? $stats['cpu']['total'] / 1000 : 0, '%cpu' => isset($stats['cpu']) ? $stats['cpu']['percent'] : 0, 'memory' => isset($stats['mu']) ? $stats['mu']['total'] : 0, '%memory' => isset($stats['mu']) ? $stats['mu']['percent'] : 0, 'min_real' => $stats['wt']['min'] / 1000, 'max_real' => $stats['wt']['max'] / 1000);
         $profile[] = $entry;
         if ($fname === 'main()') {
             $main = $entry;
         }
     }
     // Merge in all of the custom profile sections
     foreach ($this->sprofiler->getFunctionStats() as $stats) {
         if ($this->shouldExclude($stats['name'])) {
             continue;
         }
         // @note: getFunctionStats() values already in ms
         $stats['%real'] = $main['real'] ? $stats['real'] / $main['real'] * 100 : 0;
         $stats['%cpu'] = $main['cpu'] ? $stats['cpu'] / $main['cpu'] * 100 : 0;
         $stats['%memory'] = $main['memory'] ? $stats['memory'] / $main['memory'] * 100 : 0;
         $profile[] = $stats;
         // assume no section names collide with $metrics
     }
     return $profile;
 }