PHP: ottimizzare le nostre applicazioni
Il PHP è sicuramente il linguaggio server-side più utilizzato e famoso al mondo. Probabilmente sta perdendo terreno nell’ultimo periodo, lasciandolo a linguaggi come Ruby e Python però prima che venga surclassato ne passerà di acqua sotto i ponti. La maggior parte dei gestori di hosting offrono piattaforme con Apache-PHP installato, meno diffuse le piattaforme con IIS (per ASP) e Tomcat (JSP e Servlet). Uno dei problemi degli hoster, soprattutto quelli a buon mercato, è la banda che mettono a disposizione; spesso troppo esigua e questo comporta a volte delle lunghe attese di esecuzione di uno script.
Purtroppo possiamo fare poco per ovviare a questo problema, se non cambiare hosting, ma parte di quel poco che possiamo fare per velocizzare i nostri script voglio presentarlo nell’articolo di oggi. In queste righe presento alcuni trucchetti e consigli che consentono di ridurre il tempo (e lo spazio) di esecuzione di uno script.
Il metro di misura utilizzato in questo articolo è stato il seguente codice che restituisce il tempo di esecuzione di uno script:
<?php $start = microtime(true); //codice $end = microtime(true); $esito = ($end - $start); ?>
Ovviamente il tempo di esecuzione varia da server a server in base alla versione, alla configurazione hardware ecc ecc però il risultato di tale funzione ha validità quando le operazioni vengono eseguite sulla stessa macchina. Il tempo di esecuzione finale è calcolato però facendo la media su 5 esecuzioni dello stesso script al fine di evitare falsi valori.
Cominciamo intanto dai consigli base.
- echo vs print
Sono ancora molti che usano la funzione print e le sue C-derivate tipo printf, sprintf, ecc. La funzione echo però risulta molto più veloce nella chiamata rispetto alla print ed è sicuramente più dinamica dell’altra. Utilizzata adeguatamente poi, consente di ridurre ancora di più il tempo di esecuzione. Infatti anzichè concatenare le stringhe con il “.” è possibile utilizzare i multi-parametri.
//concatenazione echo "Ciao " . $nome; //multi-parametro echo( "Ciao ", $nome );
La media del tempo di esecuzione è stata:
- echo: 0.15068
- print: 0.17624
- non inventare l’acqua calda
E’ già stata scoperta secoli fa!
Inutile creare funzioni che già sono incluse nel linguaggio. Anche se si è esperti programmatori e si ottimizza al massimo spazio e tempo di esecuzione della funzione, richiamare una funzione propria anzichè una già inclusa nel linguaggio costa comunque spazio e tempo maggiori.
- apostrofi vs apici
Usare, quando possibile l’apostrofo anziche l’apice, risulta, anche se di poco, più veloce. Questo perchè il php cerca all’interno della stringa con apici le variabili, cosa che non succede con gli apostrofi.
- apostrofo: 0.14066
- apice: 0.15020
Variabili
- dichiara una variabile prima di utilizzarla
A seconda delle impostazioni del php.ini una variabile non dichiarata e non valorizzata potrebbe causare warning. A prescindere da questo però, utilizzare una variabile che è stata precedentemente dichiarata riduce di molto il tempo di esecuzione di un’operazione.
- utilizza meno variabili possibili
Un codice di questo tipo utilizza il doppio della memoria di cui necessita:
$username = $_GET['user']; $password = $_GET['pw']; $result = connect($username, $password); //oppure $array = $_SESSION['dati']; $size_array = sizeof($array); echo "L'array contiene " . $size_array . " oggetti."; printr($array);
In fatto di leggibilità dal codice alzo le mani in quanto risulta sicuramente più leggibile in questa maniera però in memoria vengono usate molte più variabili di quelle di cui effettivamente si necessita. Magari in fase di creazione dello script è utile avere codice leggibile ma prima di rilasciare il codice è il caso di eliminare quelle variabili che non servono a nulla.
$result = connect($_GET['user'], $_GET['password']); //oppure echo "L'array contiene " . sizeof( $_SESSION['dati'] ) . " oggetti."; printr( $_SESSION['dati'] );
A conti fatti si utilizza esattamente metà dello spazio in memoria.
Un altro consiglio è riutilizzare la stessa variabile quando non si necessita più del suo contenuto. Ad esempio la variabile che contiene il risultato di una prima query, quando non ci serve più, può contenere il risultato di una seconda query anzichè usarne un’altra.
UPDATE: come mi ha fatto giustamente notare StefanoV, ho omesso una cosa importante. Ottimizzare si, però con la testa. Se usiamo spesso un valore ottenuto tramite diverse chiamate a funzione è ovvio che sia più comodo tenerlo salvato in una variabile, anche se questo comporta l’utilizzo di una variabile in più. Insomma come ho detto nel commento, ottimizzazione si, ammattimento no! Un piccolo esempio per chiare il concetto:
//senza variabile aggiuntiva
if( mysql_num_rows(mysql_query("SELECT * FROM 'table'")) > 100 ) {
//...codice
echo mysql_num_rows(mysql_query("SELECT * FROM 'table'"));
} else {
echo mysql_num_rows(mysql_query("SELECT * FROM 'table'"));
}
//con variabile aggiuntiva
$rows = mysql_num_rows(mysql_query("SELECT * FROM 'table'"));
if( $rows > 100 ) {
//...codice
echo $rows;
} else {
echo $rows;
}
- libera spazio quando possibile
Abbiamo effettuato una query che ha tirato fuori 1.000 risultati dal db e abbiamo copiato il risultato in un’altra variabile. Perchè tenere memorizzati su più spazi di memoria gli stessi dati? Svuotiamo le variabili quando non ne abbiamo più bisogno attraverso la direttiva unset($variabile).
- variabili locali vs variabili globali
Operare su una variabile locale è molto più veloce piuttosto di una globale. Dichiarare una variabile globale in una funzione senza mai utilizzarla rallenta notevolmente l’esecuzione dello script.
- incrementi e decrementi di una variabile
Incrementare, o decrementare una variabile, con ++$i risulta più veloce di $i++ in quanto nell’ultimo caso deve creare una variabile temporanea.
Strutture di controllo e cicli
- operatore ternario vs if … else
Utilizzare l’operatore ternario anzichè una if … then riduce il tempo di esecuzione. Il seguente codice sortisce lo stesso effetto in entrambi i casi ma il tempo di esecuzione è inferiore.
//if ... else if($i > 0) $i += 20; else $i -= 20; //operatore ternario ($i > 0) ? $i += 20 : $i -= 20;
- if … else: 0.24080
- operatore ternario: 0.19073
- switch vs if … elseif …. elseif
Se si hanno molti controlli da fare è più indicato usare uno switch piuttosto che più if annidate. Controllare tutte le if richiede più tempo del costrutto switch.
- cicli
Innanzitutto è buona norma impostare il valore di stop di un ciclo fuori dal ciclo stesso piuttosto che al suo interno.
Poi un altro consiglio è quello di non usare chiamate a funzione per verificare il valore di stop del ciclo. Un esempio per chiarire:
//la sizeof è eseguita ad ogni ciclo quindi c'è spreco di tempo for( $i=0; $i < sizeof($j); $i++ ); //una sola chiamata a funzione $end = sizeof($j); for( $i=0; $i < $end; $i++);
Chiudo qui la prima parte dell’articolo. Preferisco spezzettarlo per lasciare il tempo di assimilare le nozioni per coloro che le hanno viste per la prima volta. Nell’ultima parte mi occuperò dell’ottimizzazione degli array, delle stringhe e della programmazione OOP.
Alla prossima
Sommario:
- PHP: ottimizzare le nostre applicazioni – (Consigli base, Variabili, Strutture di controllo e cicli)
- PHP: ottimizzare le nostre applicazioni – parte 2 - (Stringhe, Array)
- PHP: ottimizzare le nostre applicazioni – parte 3 – (OOP, MySQL)
Articolo letto 1148 volte.
Post correlati:
- PHP: ottimizzare le nostre applicazioni – parte 2
- PHP: Guida pratica all’estensione mysqli – parte 2
- PHP: ottimizzare le nostre applicazioni – parte 3
- Il foreach in php
- PHP: Guida pratica all’estensione mysqli – parte 1
- MySQL: Estrarre dei record casuali da una tabella
- jQuery: 10 tecniche per migliorare e ottimizzare i nostri script
- PHP: ottenere informazioni su un file remoto
- FirePHP, un Firebug per PHP
- Twitter: visualizzare la nostra lista preferiti
























Back to top








Cellulare: (+39) 340-8652066
Mail:
WLM:
Complimenti, articolo stupendo!!
Però non sono daccordo su una cosa… le variabili da usare in moderazione…
Nel caso che suggerisci tu: $username = $_GET['user']; ok è uno spreco… Ma ti immagini se ogni volta lo script anziche in GET dovesse accedere a cookie o sessioni? e poi magari con funzioni…
ad esempio se io dovessi inserire un dato piu volte non mi metterei a scrivere piu volte as esempio filtra_stringa(addslashes($_SESSION['nome']));
piuttosto metterei il tutto in una variabile che riutilizzerei… come per l’appunto fai nell’ultimo esempio dove inserisci sizeof in una variabile $end
Attendo con impazienza la seconda parte, complimenti
Forse $_GET['user'] non era proprio l’esempio più adatto, soprattutto considerando che sono le variabili su cui lavorare molto tra controlli, regex, ecc.
Però ho visto codice di persone che, dopo 2mila righe mi venivano a dire: “ci vuole troppo tempo che mi si carica la pagina”.
Dando una semplice, semplicissima occhiata, vedevo che lo stesso valore lo salvavano venti volte in variabili diverse. Finchè è una stringa di 10caratteri ok, sono 10byte e non muore nessuno; ma usando array o strutture dati più avanzate, query, ecc le cose si complicano e di molto!
In effetti son d’accordo con te, non mi sono spiegato proprio nel migliore dei modi. Ottimizzazione si, ammattimento no
Usare una variabile spreca spazio ma risparmi in tempo di coding, quindi è pur sempre ottimizzazione
Ottimo articolo per migliorare il proprio codice!
Grazie…mi fa piacere che sia stato gradito l’articolo
[...] Il seguito di questo articolo: PHP: ottimizzare le nostre applicazioni | Simone D'Amico [...]
Alla faccia dell’articolo che hai scritto….
Complimenti, utilissimo