Ho avuto l'idea di approfondire questo tema, partendo - situazione più comoda da gestire in questo caso - dal linguaggio C, ovvero: ciò che dichiari all'interno di un blocco, ha visibilità all'interno del blocco stesso e, molto interessante, all'uscita dal blocco viene liberata l'area di memoria interessata!. Quindi per capirci, in linguaggio C si può fare una cosa del tipo:
int x; //variabile dichiarata prima del blocco!
{
/* blocco */
int V[100000];
/* varie operazioni */
x=V[99999]; //esempio
}
printf("x=%d\n",x); //la memoria occupata nel blocco, quindi l'array V, non mi serve più quindi viene liberata e la variabile x si trova assegnato il valore che mi serve, ha visibilità al di fuori del blocco essendo stata dichiarata prima
Questo esempio mostra che, in un programma lungo e complesso, posso liberare memoria anche in questo modo (ben diverso avere un'unica variabile che contenga un valore intero, piuttosto - ad esempio - di un array di 100.000 numeri interi, se quetso non mi serve più), anche senza dover ricorrere all'allocazione dinamica della memoria (funzioni malloc()
e free()
).
Ora torniamo a PHP, perché le cose cambiano un pochino. In PHP fondamentalmente abbiamo queste due funzioni per visualizzare la memoria occupata:
memory_get_usage();
: restituisce il valore in byte della memoria PHP allocata, nel momento in cui chiamo questa funzione
memory_get_peak_usage();
: restituisce il valore in byte del picco di memoria PHP allocata, a seconda dell'algoritmo il valore può essere quindi anche molto diverso dal precedente
Vediamo quindi due casi di studio differenti.
Caso 1: codice standard
Il blocco di codice da testare, in termini di memoria occupata, è il seguente:
$array = range(1, 100000);
Vediamo tutto il codice PHP del programma.
<?php
// Memoria all'inizio dello script
$memoria_iniziale = memory_get_usage();
$memoria_picco_iniziale = memory_get_peak_usage();
// Blocco di codice da testare
$array = range(1, 100000);
// Memoria dopo il blocco di codice
$memoria_finale = memory_get_usage();
$memoria_picco_finale = memory_get_peak_usage();
// Output
echo "Memoria all'inizio: ".$memoria_iniziale." byte\n";
echo "Picco di memoria all'inizio: ".$memoria_picco_iniziale." byte\n";
echo "Memoria alla fine: ".$memoria_finale." byte\n";
echo "Picco di memoria alla fine: ".$memoria_picco_finale." byte\n";
echo "Differenza memoria: ".$memoria_finale-$memoria_iniziale." byte\n";
echo "Differenza memoria di picco: ".$memoria_picco_finale-$memoria_picco_iniziale." byte\n";
?>
Caso 2: uso di una funzione
Il blocco di codice da testare, in termini di memoria occupata, in questo caso è il seguente:
function f(){
$array = range(1, 100000);
}
f();
Quindi inserisco il blocco, l'array, all'interno di una funzione e poi richiamo questa funzione.
Vediamo tutto il codice PHP del programma.
<?php
// Memoria all'inizio dello script
$memoria_iniziale = memory_get_usage();
$memoria_picco_iniziale = memory_get_peak_usage();
// Blocco di codice da testare
function f(){
$array = range(1, 100000);
}
// Richiamo la funzione
f();
// Memoria dopo il blocco di codice
$memoria_finale = memory_get_usage();
$memoria_picco_finale = memory_get_peak_usage();
// Output
echo "Memoria all'inizio: ".$memoria_iniziale." byte\n";
echo "Picco di memoria all'inizio: ".$memoria_picco_iniziale." byte\n";
echo "Memoria alla fine: ".$memoria_finale." byte\n";
echo "Picco di memoria alla fine: ".$memoria_picco_finale." byte\n";
echo "Differenza memoria: ".$memoria_finale-$memoria_iniziale." byte\n";
echo "Differenza memoria di picco: ".$memoria_picco_finale-$memoria_picco_iniziale." byte\n";
?>
Risultati - confronto fra i due programmi
La differenza di memoria occupata è notevole, infatti:
- programma 1: la memoria occupata resta tale, non viene liberata (ricordiamo l'esempio accennato prima, linguaggio C, se l'array non serve più, eventualmente è più opportuno assegnare il valore finale ad un'unica variabile liberando quindi molta memoria)
- programma 2: la memoria occupata viene liberata, il valore finale è identico a quello iniziale! Il valore di picco invece mostra che la memoria era stata occupata, come per il caso precedente
Questo semplice accorgimento quindi, in programmi più complessi, può essere molto utile in termini di prestazioni, ottimizzazione della memoria occupata. Quindi se occorre memorizzare poi il valore della funzione (nella stessa avremo un certo return
), possiamo fare ad esempio $x=f()
e lo spazio occupato in memoria sarà solo quello di una variabile e non ad esempio di un array enorme, che non ci serve più.
Vediamo l'output di questi due programmi PHP, con i rispettivi valori di memoria occupata.