Perl LanguageMemory usage optimization

Reading files: foreach vs. while

When reading a potentially large file, a while loop has a significant memory advantage over foreach. The following will read the file record by record (by default, "record" means "a line", as specified by $/), assigning each one to $_ as it is read:

while(<$fh>) {
    print;
}

The diamond operator does some magic here to make sure the loop only terminates at end-of-file and not e.g. on lines that contain only a "0" character.

The following loop seems to work just the same, however it evaluates the diamond operator in list context, causing the entire file to be read in one go:

foreach(<$fh>) {
    print;
}

If you are operating on one record at a time anyway, this can result in a huge waste of memory and should thus be avoided.

Processing long lists

If you have a list in memory already, the straightforward and usually sufficient way to process it is a simple foreach loop:

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

This is fine e.g. for the common case of doing some processing on $item and then writing it out to a file without keeping the data around. However, if you build up some other data structure from the items, a while loop is more memory efficient:

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

Unless a reference to $item directly ends up in your result list, items you shifted off the @items array can be freed and the memory reused by the interpreter when you enter the next loop iteration.