Quando si tratta di trovare un compromesso tra tempo e risorse, Perl sceglie
quasi sempre di utilizzare più memoria. Gli scalari, in Perl,
utilizzano più memoria delle stringhe in C, gli array occupano
più memoria di questi e gli hash ne usano ancora di più.
Nonostante ci sia ancora molto da fare, le recenti release si sono occupate
di questi problemi. Per esempio, a partire dala 5,004, le chiavi duplicate
degli hash sono ripartite fra tutti gli hash che le stanno usando, in modo
che non sia necessaria una nuova riallocazione.
In certi casi, usare substr() o vec() per simulare array può essere
altamente favorevole. Per esempio, un array di mille booleani
occuperà almeno 20.000 byte di spazio, ma può essere
trasformato in un vettore di 125-byte--un considerevole risparmio di memoria.
Il modulo standard Tie::SubstrHash può anche aiutare per certi tipi
di strutture dati. Se state lavorando con strutture dati particolari (matrici,
ad esempio) i moduli che le implementano in C potrebbero usare meno memoria
degli equivalenti moduli Perl.
Un'altra cosa da provare è capire se il vostro Perl sia stato
compilato con la funziona malloc di sistema o con quella propria di Perl.
Qualunque sia la verità, provate ad usare l'altra ed osservate
se questo fa la differenza. Informazioni su malloc sono reperibili nel
file INSTALL nei sorgenti della distribuzione. Potete capire se state
usando malloc del perl digitando perl -V:usemymalloc.
Naturalmente il metodo migliore per risparmiare memoria è, in primo
luogo, non fare nulla per sprecarla. Le buone pratiche di programmazione
possono orientarsi in questa direzione:
- Non siate ingordi!
Non leggete un intero file in memoria se puoi esaminarlo linea per linea. O,
più concretamente, usate un ciclo come questo:
#
# Buona Idea
# while ()
{
# ...
}
al posto di questo:
#
# Cattiva Idea
#
@dati = ;
foreach (@dati) {
# ...
}
Quando i file che state analizzando sono piccoli, non importa molto quale
metodo usate, ma fa una enorme differenza quando essi iniziano a diventare
più grandi.
- Usate map e grep solo quando è il caso
Ricordate che sia map sia grep si aspettano una LISTA di argomenti,
quindi questo codice:
@ricercato = grep {/pattern/} ;
causerà il risucchio dell'intero file. Per file grandi, è
meglio creare un ciclo:
while () { push(@ricercato, $_) if /pattern/; }
- Evitate apici non necessari e conversioni in stringa
Non inserite tra apici stringhe di grandi dimensioni, a meno che non
sia assolutamente necessario:
my $copia = "$grande_stringa";
crea due copie di $grande_stringa (una per $copia e un'altra per la stringa
fra doppi apici), considerando che
my $copia = $grande_copia;
crea una sola copia.
Lo stesso vale per fare di un grande array una stringa:
{
local $, = "\n";
print @grande_array;
}
è molto più efficiente di un
print join "\n", @grande_array;
o
{
local $" = "\n";
print "@grande_array";
}
- Passate per reference
Passate gli array e gli hash tramite reference, non tramite valori. Per dirne
una, è il solo metodo per passare liste multiple o hash (o entrambi)
in una singola chiamata/ritorno. Inoltre, questo procedimento evita di
generare una copia di tutti i contenuti. Questo richiede un certo giudizio,
comunque, perché qualsiasi cambiamento sarè propagato di
nuovo ai dati originali. Se volete veramente mutilare (o modificare) una
copia, dovrete sacrificare la memoria necessaria per crearne una.
- Legate al disco le variabili grandi.
Per "grandi" depositi di dati (per esempio quelli che eccedono la memoria
disponibile), considerate la possibilità di utilizzare uno dei moduli
DB per immagazzinarli sul disco anziché in RAM. Ciò
penalizzerà il tempo di accesso ma è probabilmente meglio
che provacare un massiccio swapping del vostro disco rigido.
|
|
AUTORE E COPYRIGHT
Copyright (c) 1997, 1998, 1999, 2000, 2001 Tom Christiansen e Nathan
Torkington. Tutti i diritti riservati.
Questa documentazione è libera; puoi ridistribuirla e/o
modificarla secondo gli stessi termini applicati al Perl.
Indipendentemente dalle modalitè di distribuzione, tutti gli esempi di
codice in questo file sono rilasciati al pubblico dominio. Potete, e
siete incoraggiati a farlo, utilizzare il presente codice o qualunque
forma derivata da esso nei vostri programmi per divertimento o per profitto.
Un semplice commento nel codice che dia riconoscimento alle FAQ sarebbe cortese
ma non è obbligatorio. |