First of all, here is a list of the various types of for loops and optimizations that can be applied. All of them are present in each version of Perl from 5.6 to 5.20 (present) inclusive, and I believe that it is comprehensive.
for (EXPR; EXPR; EXPR)
→ "C-style for loop", extended while loop.for (EXPRX..EXPRY)
→ Range and nothing else is optimized in the counting cycle.for (@ARRAY)
→ The array and nothing else get directly, but do not flatten.for (reverse LIST)
→ None of the above optimizations apply, but the list moves in the reverse order, and not vice versa.for (LIST)
→ In a general foreach loop, the LIST expression is evaluated before the start of the loop.
When CONSTX..CONSTY smoothed (i.e., anywhere other than for (CONSTX..CONSTY) ), it is smoothed at compile time, rather than at run time.
Black box
Base memory usage:
$ perl -e'system(ps, ho, rss, 0+$$);' 1540
The general case is smoothed out.
$ perl -e'$y=2_000_000; for ((),1..$y) { system(ps, ho, rss, 0+$$); last }' 80208
Or worse. (It is flattened into an array at compile time in addition to the normal use of the stack.)
$ perl -e'for ((),1..2_000_000) { system(ps, ho, rss, 0+$$); last }' 143224
for (CONST..CONST) not smoothing.
$ perl -e'for (1..2_000_000) { system(ps, ho, rss, 0+$$); last }' 1540
Indeed, for (EXPR..EXPR) is not smoothed at all.
$ perl -e'$y=2_000_000; for (1..$y) { system(ps, ho, rss, 0+$$); last }' 1540
Even without tools, you can find out the difference in compilation time.
$ time perl -c -e'1 for 1..2_000_000' -e syntax OK real 0m0.010s user 0m0.004s sys 0m0.000s $ time perl -c -e'1 for (),1..2_000_000' -e syntax OK real 0m1.197s user 0m0.952s sys 0m0.232s
White box
A non-optimized case uses the range operator in the context of l ist. Full list in mind.
$ perl -MO=Concise,-exec -e'$y=1_000_000; 1 for (),1..$y;' ... 8 <|> range(other->9)[t3] lK/1 <-- Range operator 9 <
This is what the range flattened out at compile time is as follows:
$ perl -MO=Concise,-exec -e'1 for (),1..1_000_000;' ... 4 <$> const[AV ] s <-- Constant array 5 <1> rv2av lKPM/1 6 <
You can see that for (CONST..CONST) creates enteriter with the "S" flag. At enteriter this means it is a counting cycle.
$ perl -MO=Concise,-exec -e'1 for 1..1_000_000;' ... 4 <$> const[IV 1] s 5 <$> const[IV 1000000] s 6 <
The same goes for for (EXPR..EXPR) in general.
$ perl -MO=Concise,-exec -e'$y=1_000_000; 1 for 1..$y;' ... 8 <$> const[IV 1] s 9 <
Even for (@a) not flattened!
$ perl -MO=Concise,-exec -e'1 for @a;' ... 4 <
Double check
$ perl -MO=Concise,-exec -e'1 for (),@a;' ... 4 <
A search for the code for the "S" flag will confirm all this.