[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] The MacPerl Handicap Stakes



[This has only tangential relevance to MacPerl, I think, but the measurements
are interesting]
ajf@afco.demon.co.uk (Alan Fry) writes:
In message <199603291214.MAA14617@ns.gbnet.net> you write:
>In recent messages four different ways of importing a search pattern '$str'
>emerged as follows:
>
>$str =~ /\/(.*)\/(.*)/;
>
>while(<IN>) { if (eval('$_ =~ /$1/'.$2)) {print $_} }; ------------------ 1
>
>eval ('while(<IN>) { if ($_ =~ /'.$1.'/'.$2.') {print $_}}'); ----------- 2
>
>eval('sub match { shift =~ /'.$1.'/'.$2.'}'); --------------------------- 3
>while(<IN>) {if ( &match($_)) {print $_}};
>
>$pattern = "(?$2)$1"; --------------------------------------------------- 4
>while(<IN>) { if ($_ =~ /$pattern/) {print $_;next;}}
>
>The times over a 4,322 line file were:
>
>        (1)     83s     (84s   with 'i' modifier)
>        (2)     3.83s   (3.86s with 'i' modifier)
>        (3)     6.98s   (7.86s with 'i' modifier)
>        (4)     20.42   (22.43 with 'i' modifier)
>
>The results show up very clearly the large 'eval' overhead (1) and moderate
>sub-routine call overhead (3). The performance of the favourite:
><$str =~ /(?$2)$1/> out of Perl 5 was disappointing. Why so slow I wonder?

I suspect that using /$pattern/o instead of /$pattern/ might make a big
difference here.

>Methods 1, 2 and 3, constructed as concatenated single-quoted strings, all
>work. Re-written as interpolated double-quoted strings (A, B, C below), I
>expected them to behave identically. However not all seem to do so.
>
>while(<IN>) {if ( eval("$_ =~ /$1/$2") ) {print $_}}; ------------------- A
>eval ("while(<IN>) { if ($_ =~ /$1/$2) {print $_}}"); ------------------- B
>eval("sub match { shift =~ /$1/$2}"); ----------------------------------- C
>
>'A' gives rise to curious error messages and does not carry out the search.
>'B' does nothing at all. Only 'C' works as expected.

Lets assume that $1 is xy, $2 is i, and the first line in <IN> is 

En arche en ho logos

'A' reads the first line. It then determines the argument of eval to be

En arche en ho logos =~ /xy/i

This may or may not be parsed as valid Perl (hard to tell) but is unlikely to
do what you want.

'B' evaluates the string before starting the loops so $_ is probably empty:

while (<IN>) { if ( =~ /xy/i) { print ; }}

this is likely to cause the eval to fail during compilation.

'C' evaluates to

sub match { shift =~ /xy/i; }

which works well.

Matthias

-----
Matthias Neeracher <neeri@iis.ee.ethz.ch> http://err.ethz.ch/members/neeri.html
  "Johannes Scotus Eriugena, the greatest European philosopher of the 9th
   century, said that if reason and authority conflict, reason should be
   given preference. And if that doesn't sound reasonable to you, you'll
   just have to accept it..."