Re: efficiency of if ( my @a = /pattern/g ) { print "@a\n" }



jidanni@xxxxxxxxxxx wrote:
Gentlemen, is this the most efficient way to do this, or should one use
split() and more arrays and loops?

use strict;
use warnings FATAL => 'all';
while (<DATA>) {
if ( my @a = /BB|BM|MY|SG|TW|US/g ) { print "@a\n" }
}
__DATA__
BD BE BF BG BA BB WF BM BN BO BH BI BJ BT JM BV BW WS...
BD BE BF BG BA BB WF BN BO BH BI BJ BT JM BV BW WS BR...
BD WF BF BG BA BB BE BM BN BO BH BI BJ BT JM JO WS BS BY BZ...
PR FR GU IL KR VI CA JP IT US TW NZ AU GB BR IN NL IE MX ES...

You can answer that yourself by benchmarking (perldoc Bench)
other solutions. The following isn't exactly the same, since
it's looking for the exact values, instead of something
that might contain BB or BM or MY, etc. but looking at
your data, you're possibly after the exact value.

my %item = map{ $_ => 1 } qw( BB BM MY SG TW US );
while( <DATA> )
{
my @a;
for my $k ( split( / / ) )
{
push( @a, $k ) if $item{ $k };
}
print "@a\n" if @a;
}

That's 37% faster, on my machine.

If this is all your code is doing, then it would be good
to experiment a bit. If the code is doing many other things,
then it won't matter that much. e.g. A slight
optimization, depending on the input, would be to only
split up the values, if one exists in the line:

next unless /BB|BM|MY|SG|TW|US/;

or maybe using egrep might be better:

egrep 'BB|BM|MY|SG|TW|US' file | script.pl

Of course, if every line has one of those values, then
that's a useless thing to do.

If you're really doing this a lot or are just playing around
to find if something else might be faster, experiment a
bit with different solutions. The Bench module, provides
a means to measure different solutions, against each other.
.