Как я могу измерить скорость кода, написанного на PHP?


Как я могу сказать, какой класс из многих (которые все выполняют одну и ту же работу) выполняется быстрее? есть ли программное обеспечение для измерения этого?

10 95

10 ответов:

вы (по крайней мере) два решения :

довольно "наивный"использует microtime(true) до и после части кода, чтобы узнать, сколько времени прошло во время его выполнения ; другие ответы говорили об этом и уже приводили примеры, поэтому я не буду говорить намного больше.

Это хорошее решение, если вы хотите проверить пару инструкций; например, сравнить два типа функций, например-лучше, если это делается тысячи раз, чтобы убедиться, что любой "возмущающий элемент" усредняется.

что-то вроде этого, поэтому, если вы хотите знать, сколько времени требуется для сериализации массива :

$before = microtime(true);

for ($i=0 ; $i<100000 ; $i++) {
    serialize($list);
}

$after = microtime(true);
echo ($after-$before)/$i . " sec/serialize\n";

не идеально, но полезно, и это не займет много времени, чтобы настроить.



другое решение, которое работает довольно хорошо, если вы хотите определить, какая функция занимает много времени во всем скрипте, заключается в использовании:

для быстрого материала я делаю это (в PHP):

$startTime = microtime(true);
doTask(); // whatever you want to time
echo "Time:  " . number_format(( microtime(true) - $startTime), 4) . " Seconds\n";

вы также можете использовать профилировщик, как http://xdebug.org/.

Я сделал простой класс синхронизации, может быть, это полезно для кого-то:

class TimingHelper {

    private $start;

    public function __construct() {
        $this->start = microtime(true);
    }

    public function start() {
        $this->start = microtime(true);
    }

    public function segs() {
        return microtime(true) - $this->start;
    }

    public function time() {
        $segs = $this->segs();
        $days = floor($segs / 86400);
        $segs -= $days * 86400;
        $hours = floor($segs / 3600);
        $segs -= $hours * 3600;
        $mins = floor($segs / 60);
        $segs -= $mins * 60;
        $microsegs = ($segs - floor($segs)) * 1000;
        $segs = floor($segs);

        return 
            (empty($days) ? "" : $days . "d ") . 
            (empty($hours) ? "" : $hours . "h ") . 
            (empty($mins) ? "" : $mins . "m ") . 
            $segs . "s " .
            $microsegs . "ms";
    }

}

использование:

$th = new TimingHelper();
<..code being mesured..>
echo $th->time();
$th->start(); // if it's the case
<..code being mesured..>
echo $th->time();

// result: 4d 17h 34m 57s 0.00095367431640625ms 

вот прямой ответ на ваш вопрос

есть ли программное обеспечение для измерения этого?

Да, есть. Мне интересно, почему никто еще не упомянул об этом. Хотя ответы, предложенные выше, кажутся прекрасными для быстрой проверки, но не масштабируются в долгосрочной перспективе или для более крупного проекта.

Почему бы не использовать инструмент мониторинга производительности приложений (APM), которые строятся именно для этого и многое другое. Проверьте NewRelic, AppDynamics, Ruxit (у всех есть бесплатная версия) для мониторинга времени выполнения, использования ресурсов, пропускной способности каждого приложения до уровня метода.

Я хотел бы поделиться с вами самодельной функцией, которую я использую для измерения скорости любой существующей функции до 10 аргументов:

function fdump($f_name='', $f_args=array()){

    $f_dump=array();
    $f_result='';

    $f_success=false;

    $f_start=microtime();
    $f_start=explode(' ', $f_start);
    $f_start=$f_start[1] + $f_start[0];

    if(function_exists($f_name)){

        if(isset($f_args[0])&&is_array($f_args[0])){
            if($f_result=$f_name($f_args)){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[1])){
            if($f_result=$f_name($f_args[0])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[2])){
            if($f_result=$f_name($f_args[0],$f_args[1])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[3])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[4])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[5])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[6])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[7])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[8])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[9])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8])){
                $f_success=true;
            }
        }
        elseif(!isset($f_args[10])){
            if($f_result=$f_name($f_args[0],$f_args[1],$f_args[2],$f_args[3],$f_args[4],$f_args[5],$f_args[6],$f_args[7],$f_args[8],$f_args[9])){
                $f_success=true;
            }
        }
    }
    $f_end=microtime();
    $f_end=explode(' ', $f_end);
    $f_end=$f_end[1] + $f_end[0];

    $f_time=round(($f_end - $f_start), 4);
    $f_dump['f_success']=$f_success;
    $f_dump['f_time']=$f_time;
    $f_dump['f_result']=$f_result;

    var_dump($f_dump);exit;

    //return $f_result;

}

пример

function do_stuff($arg1='', $arg2=''){
    return $arg1.' '.$arg2;
}

fdump('do_stuff',array('hello', 'world'));

возвращает

  array(3) {
    ["f_success"]=>
    bool(true)
    ["f_time"]=>
    float(0)            //too fast...
    ["f_result"]=>
    string(11) "hello world"
  }

Если вы хотите быстро проверить производительность фреймворка, вы можете вставить .php file

//at beginning
$milliseconds = round(microtime(true) * 1000);

//and at the end
echo round(microtime(true) * 1000) - $milliseconds;

каждый раз, когда вы получите время казни в МС. Потому что микросекунды не слишком полезны при тестировании фреймворка.

Если это что-то, что может быть протестировано вне веб-контекста, я просто использую Unix .

Zend Studio имеет встроенную поддержку профилирования с помощью XDebug или ZendDebugger. Он будет профилировать ваш код, сообщая вам точно, сколько времени заняла каждая функция. Это фантастический инструмент для выяснения, где ваши узкие места.

вы можете использовать основные вещи, такие как хранение меток времени или microtime() до и после операции для расчета необходимого времени. Это легко сделать, но не очень точный. Может быть, лучшим решением является Xdebug, Я никогда не работал с ним, но это, кажется, самый известный PHP отладчик/профилировщик, который я могу найти.