Which is the best implementation(in terms of speed and memory usage) for iterating through a Perl array? Is there any better way? (@Array
need not be retained).
foreach (@Array) { SubRoutine($_); }
while($Element=shift(@Array)) { SubRoutine($Element); }
while(scalar(@Array) !=0) { $Element=shift(@Array); SubRoutine($Element); }
for my $i (0 .. $#Array) { SubRoutine($Array[$i]); }
map { SubRoutine($_) } @Array ;
In each iteration, you can process each element of the list separately. This is why the for loop statement is sometimes referred to as foreach loop. In Perl, the for and foreach loop are interchangeable, therefore, you can use the foreach keyword in where you use the for keyword.
To access a single element of a Perl array, use ($) sign before variable name. You can assume that $ sign represents singular value and @ sign represents plural values. Variable name will be followed by square brackets with index number inside it. Indexing will start with 0 from left side and with -1 from right side.
EDIT: from perldoc perlvar : $# is also used as sigil, which, when prepended on the name of an array, gives the index of the last element in that array.
A foreach loop is used to iterate over a list and the variable holds the value of the elements of the list one at a time. It is majorly used when we have a set of data in a list and we want to iterate over the elements of the list instead of iterating over its range.
In terms of speed: #1 and #4, but not by much in most instances.
You could write a benchmark to confirm, but I suspect you'll find #1 and #4 to be slightly faster because the iteration work is done in C instead of Perl, and no needless copying of the array elements occurs. ($_
is aliased to the element in #1, but #2 and #3 actually copy the scalars from the array.)
#5 might be similar.
In terms memory usage: They're all the same except for #5.
for (@a)
is special-cased to avoid flattening the array. The loop iterates over the indexes of the array.
In terms of readability: #1.
In terms of flexibility: #1/#4 and #5.
#2 does not support elements that are false. #2 and #3 are destructive.
If you only care about the elements of @Array
, use:
for my $el (@Array) { # ... }
or
If the indices matter, use:
for my $i (0 .. $#Array) { # ... }
Or, as of perl
5.12.1, you can use:
while (my ($i, $el) = each @Array) { # ... }
If you need both the element and its index in the body of the loop, I would expect using each
to be the fastest, but then you'll be giving up compatibility with pre-5.12.1 perl
s.
Some other pattern than these might be appropriate under certain circumstances.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With