http://qs1969.pair.com?node_id=61486


in reply to Re: Re: Assining data to an array is slow..
in thread Assining data to an array is slow..

The key to understanding Perl as it works is 'context'. Every operation takes place in some sort of context -- that means, its results will be evaluated as a single item or as a list of items. (There is also 'void' context and boolean context, which are more or less official but not germane to the discussion.)

For example, evaluating a list in scalar context produces the number of elements in the list. In list context, it produces the elements of a list:

my @list = (1, 2, 3); # list context, @list -> (1, 2, 3) my $num = @list; # scalar context, $num -> 3 my @second_list = @list; # list context, @second_list -> (1, 2, 3)
Perl the interpreter is smart enough not to do more work than it has to (in most cases), so it usually determines the context of an operation before performing the operation to weasel out of extra work or to produce the right results for the context. You can do the same if you use wantarray().

This is important because unpack performs differently in scalar and in list context. Its perldoc page says that in scalar context, it returns just the first value. In list context, it returns all values.

In your first code snippet, it's evaluated in scalar context (more properly void, but we'll keep this simple). Perl can tell that you don't care about the return values, so it only has to unpack the first bit of data. It ignores the rest. (Since it's in void context, it may *completely* ignore the *entire* string, but I haven't looked at the source.)

This means the first snippet isn't doing as much work as the second, even in the unpack statement itself. Put aside the array assignment for the moment -- besides that, the two snippets aren't doing an equal amount of work!

To find out how much work the unpack would do in list context, put it in list context:

while ($row = <FH>) { () = unpack("a9 a40 a15 a15 a15 a2 a9 a9 a9",$row); }
This will be a more meaningful benchmark.

Besides all that, Perl handles memory internally via a reference-like mechanism. None of this tedious copying-the-contents-of-one-location-to-another jive you get in C. So the overhead is creating an array structure and populating it with the things unpack returns anyway. It's a whole lot smarter about these things than C.

In short, don't worry about memory management in Perl for now.