Angle Brackets vs. foreach

N

Nathan.Neff

I recently encountered a performance problem which was fixed by
changing:

while($file = <@files>)

to

foreach $file(@files)

Can anyone explain the reason for the performance hit? My program took
3 minutes using the <> operator, vs. about 2 seconds using foreach.

I realize that the angle brackets operator <> is not really for list
iteration. But when you evaluate it in scalar context, it does return
the contents of the list, one by one.

What is Perl doing that causes such a hit?

Thanks,

--Nate
 
R

Richard Gration

I recently encountered a performance problem which was fixed by
changing:

Not really. You changed the code so that it did something different which
took less time. Probably. It's hard to say for sure.

The while and the foreach do different things.
while($file = <@files>)

From "perldoc perlop":

"If what's within the angle brackets is neither a filehandle nor a simple
scalar variable containing a filehandle name, type-glob, or typeglob
reference, it is interpreted as a filename pattern to be globbed, and
either a list of filenames or the next filename in the list is returned,
depending on context."

As I understand the above, @files will be used as a pattern to be globbed.
This means the elements of @files will be joined with the value of $" and
the resulting string will be globbed. The default value of $" is a space,
which will result in such a string that the effect will be that each
element of @files will be treated as a pattern to be globbed. IFF no
filename is returned as a result of globbing a particular pattern, will
the pattern itself be returned.

So the number of iterations of the while loop above depends on the
contents of @files and the names of the files in the current directory for
your executing script.

For example, if your CWD contains these files: 1.txt 2.txt 3.dat
then these values of @files will return the given lists when globbed using
<@files> ...

@files = ('txt') returns ('txt') # no match (no wildcard)
@files = ('*txt') returns ('1.txt','2.txt') # 2 matches
@files = ('*txt','dat') returns ('1.txt','2.txt','dat') # no wildcard
@files = ('*txt','*dat') returns ('1.txt','2.txt','3.dat')
foreach $file(@files)

This merely iterates over the elements of @files in the standard way.
Can anyone explain the reason for the performance hit? My program took
3 minutes using the <> operator, vs. about 2 seconds using foreach.

I realize that the angle brackets operator <> is not really for list
iteration. But when you evaluate it in scalar context, it does return
the contents of the list, one by one.

Not exactly. See above.
What is Perl doing that causes such a hit?

It's hard to say without knowing the contents of your loop.

Rich
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top