Come posso misurare la velocità del codice scritto in PHP? [chiuso]


118

Come posso dire quale classe di molte (che fanno tutti lo stesso lavoro) vengono eseguite più velocemente? esiste un software per misurarlo?

Risposte:


195

Hai (almeno) due soluzioni:

Quello abbastanza "ingenuo" sta usando il microtime (vero) prima e dopo una porzione di codice, per ottenere quanto tempo è passato durante la sua esecuzione; altre risposte lo dicevano e fornivano già esempi, quindi non dirò molto di più.

Questa è una buona soluzione se vuoi confrontare un paio di istruzioni; come confrontare due tipi di funzioni, per esempio: è meglio se fatto migliaia di volte, per assicurarsi che venga calcolata la media di ogni "elemento perturbante".

Qualcosa di simile, quindi, se vuoi sapere quanto tempo ci vuole per serializzare un array:

$before = microtime(true);

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

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

Non perfetto, ma utile e la configurazione non richiede molto tempo.



L'altra soluzione, che funziona abbastanza bene se vuoi identificare quale funzione richiede molto tempo in un intero script, è usare:

  • L' estensione Xdebug , per generare dati di profilazione per lo script
  • Software che legge i dati di profilazione e ti presenta qualcosa di leggibile. Conosco tre di questi:
    • Webgrind ; interfaccia web ; dovrebbe funzionare su qualsiasi server Apache + PHP
    • WinCacheGrind ; solo su Windows
    • KCacheGrind ; probabilmente solo Linux e simili a Linux; Questo è quello che preferisco, a proposito

Per ottenere file di profilatura, devi installare e configurare Xdebug; dai un'occhiata alla pagina Profiling PHP Scripts della documentazione.

Quello che faccio generalmente non è abilitare il profiler di default (genera file abbastanza grandi e rallenta le cose) , ma utilizzare la possibilità di inviare un parametro chiamato XDEBUG_PROFILEcome GET data, per attivare la profilazione solo per la pagina di cui ho bisogno.
La parte relativa alla profilazione del mio php.ini è simile a questa:

xdebug.profiler_enable = 0              ; Profiling not activated by default
xdebug.profiler_enable_trigger = 1      ; Profiling activated when requested by the GET parameter
xdebug.profiler_output_dir = /tmp/ouput_directory
xdebug.profiler_output_name = files_names

(Leggi la documentazione per maggiori informazioni)

Questo screenshot proviene da un programma C ++ in KcacheGrind: (fonte: sourceforge.net ) Otterrai esattamente lo stesso tipo di cose con gli script PHP ;-) (Con KCacheGrind, voglio dire; WinCacheGrind non è buono come KCacheGrind ... )http://kcachegrind.sourceforge.net/html/pics/KcgShot3Large.gif



Ciò ti consente di ottenere una buona visione di ciò che richiede tempo nella tua applicazione e talvolta aiuta definitivamente a individuare il file funzione che sta rallentando tutto ^^

Nota che Xdebug conta il tempo di CPU impiegato da PHP; quando PHP attende una risposta da un database (per esempio), non funziona; solo in attesa. Quindi Xdebug penserà che la richiesta DB non richieda molto tempo!
Questo dovrebbe essere profilato sul server SQL, non PHP, quindi ...


Spero che questo sia utile :-)
Buon divertimento!


1
Esiste una build per Windows di QCacheGrind :-) sourceforge.net/projects/qcachegrindwin
François Breton

43

Per cose veloci lo faccio (in PHP):

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

Puoi anche utilizzare un profiler come http://xdebug.org/ .


2
Per una maggiore precisione, suggerirei (a) di utilizzare un ciclo e calcolare la media del tempo e (b) di utilizzare file separati per ogni cosa che stai testando. Se hai diversi tempi in uno script, il loro ordine a volte può fare la differenza.
DisgruntledGoat

9

Ho fatto una semplice lezione di cronometraggio, forse è utile a qualcuno:

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";
    }

}

Uso:

$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 

Hai echo$echo
digitato male

9

Aggiornamento 2020

Sono passati molti anni dall'ultima volta che ho risposto a queste domande, quindi ho pensato che questo meritasse un aggiornamento sul panorama APM.

  • AppDynamics è stato acquistato da Cisco e l'account gratuito per sempre che offrivano è stato rimosso dal loro sito web.
  • NewRelic ha abbassato i prezzi da $ 149 / mese / host a $ 25 / mese / host per competere con il nuovo arrivato sul mercato APM, Datadog che offre $ 31 / mese / host.
  • Le funzionalità di Datadog APM sono ancora leggere e lasciano molto a desiderare. Tuttavia, li vedo migliorare e migliorare questi nel corso del prossimo anno.
  • Ruxit è stato acquistato da Dynatrace. Nessuno shock qui dato che Ruxit è costruito da ex dipendenti Dynatrace. Ciò ha permesso a Dynatrace di trasformarsi in un vero modello SaaS per migliorare. Dì addio a quel client Java ingombrante, se lo desideri.
  • Ora ci sono anche opzioni gratuite / open source. Acquista Apache Skywalking che è molto popolare in Cina tra i loro migliori aziende di tecnologia e PinPoint , che offre una demo che si può provare prima di procedere all'installazione. Entrambi richiedono la gestione dell'hosting, quindi preparati a far girare poche macchine virtuali e dedica del tempo all'installazione e alla configurazione.
  • Non ho provato nessuna di queste soluzioni APM opensource, quindi non sono nella posizione di consigliarle, tuttavia, ho gestito personalmente l'implementazione di tutte queste soluzioni APM per più organizzazioni sia in sede che su cloud per centinaia di applicazioni / microservices. Quindi posso dire con sicurezza che non puoi sbagliare con nessuno dei fornitori se si adattano al tuo conto.


Risposta originaria nell'ottobre 2015

Ecco una risposta diretta alla tua domanda

esiste un software per misurarlo?

Si C'è. Mi chiedo perché nessuno lo abbia ancora menzionato. Anche se le risposte suggerite sopra sembrano andare bene per un controllo rapido ma non sono scalabili a lungo termine o per un progetto più grande.

Perché non utilizzare uno strumento APM (Application Performance Monitoring) creato esattamente per questo e molto altro ancora. Dai un'occhiata a NewRelic, AppDynamics, Ruxit (tutti hanno una versione gratuita) per monitorare il tempo di esecuzione, l'utilizzo delle risorse, il throughput di ogni applicazione a livello di metodo.


6

Se vuoi testare velocemente le prestazioni di un framework, puoi metterlo nel file index.php

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

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

Ogni volta otterrai il tempo di esecuzione in millisecondi . Perché i microsecondi non sono troppo utili per testare un case framework.



4

Vorrei condividere con voi una funzione autocostruita che utilizzo per misurare la velocità di qualsiasi funzione esistente fino a 10 argomenti:

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;

}

Esempio

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

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

ritorna

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

3

Se è qualcosa che può essere testato al di fuori del contesto Web, utilizzo semplicemente il timecomando Unix .


3

Zend Studio ha il supporto integrato per la creazione di profili utilizzando XDebug o ZendDebugger. Profilerà il tuo codice, dicendoti esattamente quanto tempo ha impiegato ogni funzione. È uno strumento fantastico per capire dove sono i tuoi colli di bottiglia.


1

È possibile utilizzare elementi di base come memorizzare timestamp o microtime () prima e dopo un'operazione per calcolare il tempo necessario. È facile da fare, ma non molto preciso. Forse una soluzione migliore è Xdebug , non ci ho mai lavorato ma sembra essere il debugger / profiler PHP più conosciuto che riesco a trovare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.