Zoeken…


Bestanden lezen: foreach versus while

Bij het lezen van een potentieel groot bestand heeft een while lus een aanzienlijk geheugenvoordeel ten opzichte van foreach . Het volgende zal het bestand record voor record lezen (standaard betekent "record" "een regel", zoals gespecificeerd door $/ ), waarbij elk bestand wordt toegewezen aan $_ zoals het is gelezen:

while(<$fh>) {
    print;
}

De diamantoperator doet hier wat magie om ervoor te zorgen dat de lus alleen eindigt aan het einde van het bestand en niet bijvoorbeeld aan lijnen die alleen een "0" -teken bevatten.

De volgende lus lijkt precies hetzelfde te werken, maar evalueert de diamantoperator in lijstcontext, waardoor het hele bestand in één keer wordt gelezen:

foreach(<$fh>) {
    print;
}

Als u toch op één record tegelijk werkt, kan dit leiden tot een enorme verspilling van geheugen en moet daarom worden vermeden.

Lange lijsten verwerken

Als je al een lijst in het geheugen hebt, is de eenvoudige en meestal voldoende manier om deze te verwerken een eenvoudige foreach lus:

foreach my $item (@items) {
    ...
}

Dit is prima, bijvoorbeeld voor het algemene geval van enige verwerking van $item en het vervolgens naar een bestand te schrijven zonder de gegevens te bewaren. Als u echter een andere gegevensstructuur van de items opbouwt, is een while lus geheugenefficiënter:

my @result;
while(@items) {
    my $item = shift @items;
    push @result, process_item($item);
}

Tenzij een verwijzing naar $item @items rechtstreeks in uw resultatenlijst terechtkomt, kunnen items die u uit de array @items hebt verplaatst, worden vrijgegeven en het geheugen opnieuw worden gebruikt door de interpreter wanneer u de volgende @items start.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow