Iterating loop
foreach my $i (...list...) { ... }
The list is flattened (requiring memory proportional to the size of the list).
C-style loop
for (...; ...; ...) { ... }
Utmost flexibility. Utmost efficiency. Least readable.
Counting loop
for my $i ($x..$y) { ... }
This is a special case of the iterating loop that uses no memory. When the list consists of a range, it is not flattened. Utmost efficiency. Utmost Readability.
Reverse Iterating loop
foreach my $i (reverse ...list...) { ... }
This is a special case of the iterating loop. Instead of actually reversing the list, the list is processed in reverse. You save the cost of the reverse operation, but that's it. The list is still flattened (even if it's just a range), so it still requires memory proportional to the size of the list.
My personal convention is to write counting loops and C-style loops using for, and iterating loops using foreach. That way, the extra cost of flattening the list is not hidden. However, Perl will gladly accept both for and foreach in every case.
Update: Since posting this, I have been told Reverse Iterating loop has been improved such that it no longer flattens the list, but the following snippet shows that it hasn't been "fixed" in the latest stable version of Perl (Perl 5.8.8).
use strict; use warnings; print("$]\n"); # 5.008008 # Don't inline these. It will cause the # memory to be allocated at compile time. my $min = 0; my $max = 10_000_000; for ( $min .. $max) { print(":"); <STDIN>; last; } # 2.2MB for (reverse $min .. $max) { print(":"); <STDIN>; last; } # 239MB
The person must have been misinterpreted perl586delta. perl586delta only says "a temporary reversed list isn't created". The temporary flattened list is still created.
In reply to Re: Risks of equivalence between FOR and FOREACH
by ikegami
in thread Risks of equivalence between FOR and FOREACH
by throop
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |