Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [PHP] Misurare l'overhead

    Ciao,
    mi sono reso conto dell'impossibilità di misurare l'overhead di uno script.
    L'ordine di lettura del parser infatti è:
    [list=1][*]definizioni (di classi e funzioni)[*]assegnazioni[*]svolgimento della procedura[/list=1]
    Questo vuol dire che se a monte dello script, prima di qualsiasi definizione delle classi e quant'altro inserisco:

    Codice PHP:
    <?php
    $start_parsing 
    microtime(1);
    // definizione delle classi...

    $t1 microtime(1);
    ?>
    il timestamp associato a quella variabile non sarà mai quello dell'inizio del parsing, ma sempre quello di inizio dell'esecuzione dello script, infatti $t1 - $start_parsing è sempre zero.

    Qualcuno ha esperienza in merito?
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  2. #2
    mah secondo me non puoi misurarlo all'interno del codice php che vuoi misurare.. dovresti farti un programmino esterno che misuri il tempo da quando il programma php è stato chiamato a quando questo ha terminato e sottrargli il tempo invece che misuri all'interno dello script.. tempo che cmq penso sia trascurabile sinceramente..
    IP-PBX management: http://www.easypbx.it

    Old account: 2126 messages
    Oldest account: 3559 messages

  3. #3
    Originariamente inviato da Santino83_02
    mah secondo me non puoi misurarlo all'interno del codice php che vuoi misurare.. dovresti farti un programmino esterno che misuri il tempo da quando il programma php è stato chiamato a quando questo ha terminato e sottrargli il tempo invece che misuri all'interno dello script.. tempo che cmq penso sia trascurabile sinceramente..
    Sì, avevo già pensato di aprire la risorsa internamente allo stesso server con un socket per farmi un'idea dell'overhead, ma non potrò misurarlo in modo autonomo dallo script ad ogni sua chiamata, è corretto?

    In ASP c'è lo stesso limite, dovuto all'ordine di lettura del parser? (Dal logo desumo tu sia ben ferrato in ASP).
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  4. #4
    Ciao,

    si certo, c'è lo stesso identico limite. In realtà, comunque, è un test importante per misurare le performance del codice php che hai scritto! L'esecuzione, per intero, della pagina web richiede tante altre operazioni che ovviamente fanno levitare il tempo di esecuzione complessivo. Per poter fare un test SERIO hai bisogno di 2 computer, uno che faccia da server e l'altro da client, collegati su rete ad 1gbit.

    Sul server magari una bella distro linux (una debian 5 o una ubuntu 9.10 server) con dentro il tuo applicativo che gira su apache e poi il client che, tramite ab, testa l'esecuzione del dello script sul server (ab fa N richieste al secondo simulando M client contemporanei) per vedere il tempo di esecuzione medio sotto stress

    Non ha senso fare quest'ultimo test, ripeto, se non si hanno 2 macchine perché usando una sola macchina le performance scenderanno, ovviamente, sotto zero!

  5. #5
    Utente di HTML.it L'avatar di bubi1
    Registrato dal
    Dec 2009
    Messaggi
    1,230

    Re: [PHP] Misurare l'overhead

    Originariamente inviato da emanueledg

    Questo vuol dire che se a monte dello script, prima di qualsiasi definizione delle classi e quant'altro inserisco:

    Codice PHP:
    <?php
    $start_parsing 
    microtime(1);
    // definizione delle classi...

    $t1 microtime(1);
    ?>
    il timestamp associato a quella variabile non sarà mai quello dell'inizio del parsing, ma sempre quello di inizio dell'esecuzione dello script, infatti $t1 - $start_parsing è sempre zero.

    Qualcuno ha esperienza in merito?
    E' 0 perche' fai i calcoli sbagliati.
    la differenza tra due chiamate a microtime() su una macchina decente sara' nell'ordine di 10^-4 ms, ma non sara' mai 0.
    Tu chiami microtime(1) (quindi richiedi che te lo restituisca in float: sec,msec) che ti fa un arrotondamento ai msec, per il semplice motivo del limite delle cifre dei float sul tuo sistema a 32 o 64 bit.

    Per quanto riguarda il resto, io la misurazione la faccio in 2 modi:
    1. Se devo far vedere all'utente la solita frase "processato in x secondi", uso i soliti metodi, chi se ne frega della precisione
    2. Se mi serve misurare con precisione il tempo di esecuzione di uno script tenendo in considerazione il tempo del parser, etc, faccio semplicemente da bash un: time php script.php

    ad esempio sul tuo script:
    Codice PHP:
    <?php
    $start_parsing 
    microtime(1);
    sleep(1);
    $t1 microtime(1);
    echo 
    $t1-$start_parsing."\n";
    ?>
    da' il risultato
    codice:
    # time php a.php
    1.00112819672
    
    real    0m1.040s
    user    0m0.020s
    sys     0m0.016
    da dove risulta un overhead di 39ms.

  6. #6

    Due workaround parziali

    Grazie dei vostri feedback.

    @Daniele: non sapevo che un test veritiero richiedesse necessariamente due macchine indipendenti, pensavo che con l'apertura di una connessione curl locale avrei risolto.
    Quali sono le operazioni che il server deve fare e che io non vedo, prima e dopo PHP? (Giusto per averne un'idea, così mi documento).

    @bubi1: hai ragione, microtime(true) restituisce un float arrotondato alla quinta cifra decimale (decimi di millisecondo), ma davo per scontato che il caricamento delle classi definite prendesse più tempo, e quell'apprezzamento mi basta perché non voglio sapere i microcicli, dovendo valutare i tempi rispetto a quelli umani (finché si parla di centesimi di secondo o tempi maggiori ne tengo conto, se sono inferiori non me ne preoccupo).


    Ho individuato due workaround parzialmente validi per fare una misurazione del solo caricamento delle classe definite:
    [list=1][*]il puntatore del parser procede per files; pertanto se il file con le classi di cui monitorare il tempo di parsing è un file PHP incluso, posso rilevare correttamente i timestamp pre e post-inclusione:

    Codice PHP:
    echo 'class test exists: '.(int)class_exists('test'); // falso;
    $t1 microtime();
    include(
    'test.class.php');
    $t2 microtime();
    echo 
    'class test exists: '.(int)class_exists('test'); // vero;

    $t1 explode(' '$t1);
    $t1 = (float)$t1[0] + (float)$t1[1];

    $t2 explode(' '$t2);
    $t2 = (float)$t2[0] + (float)$t2[1];

    echo 
    'elapsed: '.($t2 $t1); 
    Risultato: (media su 50 richieste) 0.003
    Svantaggi: al tempo di parsing si aggiunge il tempo di accesso alla risorsa esterna del filesystem.
    [*]Dal momento che le procedure vengono parsate per ultime, innestando la definizione delle classi in un semplice controllo condizionale posso rilevare i timestamp precedenti e successivi ad esso:

    Codice PHP:
    echo 'class test exists: '.(int)class_exists('test'); // falso;
    $t1 microtime();
    if (
    true) {
        class 
    test {
            
    // bla bla...
        
    }
    }
    $t2 microtime();
    echo 
    'class test exists: '.(int)class_exists('test'); // vero;

    $t1 explode(' '$t1);
    $t1 = (float)$t1[0] + (float)$t1[1];

    $t2 explode(' '$t2);
    $t2 = (float)$t2[0] + (float)$t2[1];

    echo 
    'elapsed: '.($t2 $t1); 
    Risultato: (media su 50 richieste) 0.00021
    Svantaggi: una zozzeria del genere di certo non la metto nel mio codice finale!
    [/list=1]



    I test li ho fatti su Windows XP in locale, sul laptop con 2GB di RAM e processore da 1.8GHz.
    Almeno ho un'idea dell'ordine di grandezza del caricamento.
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  7. #7

    Re: Due workaround parziali

    Originariamente inviato da emanueledg
    @Daniele: non sapevo che un test veritiero richiedesse necessariamente due macchine indipendenti, pensavo che con l'apertura di una connessione curl locale avrei risolto.
    Quali sono le operazioni che il server deve fare e che io non vedo, prima e dopo PHP? (Giusto per averne un'idea, così mi documento).
    le operazioni sono tante, e, ovviamente, dipendono dal webserver utilizzato. Nel caso specifico di Apache, dipende dal sistema operativo per via del fatto che è in grado di caricare un modulo di gestione delle connessioni ad hoc (i cosidetti MPM).

    Diciamo che, in generale, un webserver, ogni volta che accedi ad una pagina, deve prima di tutto accettare la connessione, passare la richiesta ad un thread già esistente o avviarne uno nuovo, iniziare a ricevere i dati, parsare i dati, una volta acquisito l'header della richiesta, deve inizializzare un contesto per la richiesta stessa, iniziare a chiedere ai vari moduli prima di filtraggio e poi gli endpoint che fare e che non fare con la richiesta nel frattempo che continua a ricevere e a passare i dati e per finire deve risponderti.

    Ovviamente quello che ho riportato è un "semplice" schemino delle operazioni minimali che un webserver compie (considera che il webserver deve tenere traccia dei dati che passi, o anche del semplice fatto che la il browser ha terminato la richiesta ma la socket deve rimanere aperta, in attesa di dati, per altri N secondi, in base alla configurazione del Keep Alive e via dicendo)

    I due computer si rendono necessari perché se vuoi avere un test "realistico" devi mettere sotto stress tutto che significa portare la macchina al limite a passi (ovvero inizi con un carico ben preciso e poi vai crescendo per vedere come risponde il software alle richieste fin quando non vedi che i tempi sono diventati eccessivi e non ha senso continuare). Se portassi la macchina al limite con sia il software di stress sia il software da stressare, beh, non sarebbe un limite "realistico" perché oltre al sistema operativo che, anche se poco, si pappa risorse ... il software di stress si farebbe sentire

    Ho individuato due workaround parzialmente validi per fare una misurazione del solo caricamento delle classe definite:
    1. il puntatore del parser procede per files; pertanto se il file con le classi di cui monitorare il tempo di parsing è un file PHP incluso, posso rilevare correttamente i timestamp pre e post-inclusione:
      .
      .
      .

    I test li ho fatti su Windows XP in locale, sul laptop con 2GB di RAM e processore da 1.8GHz.
    Almeno ho un'idea dell'ordine di grandezza del caricamento.
    perché non usare XDebug?
    http://www.xdebug.com

    Dai un occhio qua
    http://www.xdebug.com/docs/profiler

  8. #8
    Ah ok, la negoziazione come aspetto formale del dialogo client-server la conosco, le specifiche operazioni tecniche del server a basso livello come il log delle richieste, la gestione del socket, le verifiche dei moduli etc invece no.

    Interessante XDebug, in pratica fa lo stesso lavoro di Zend Studio, vero?
    Solo che è free
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  9. #9

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.