----- Original Message -----
To: renard
Sent: Tuesday, September 13, 2005 11:01 AM
Subject: Re: regexp /o in a sub


Renard,

First, let me apologize for top-posting; we use Lotus Notes and this is how it replies.

Now, someone else suggested something similar to your idea below, and I am playing around with these ideas. But let me say this: the value of $row (the selector in the for-do loop) is guaranteed to match one of the loop's possibilities on each pass through the subroutine, so your fear of (what would turn out to be) an infinite loop-ing is groundless. Also, some of the possibilities--six, in fact--contain multiple lines of code. I don't know enough Perl yet to handle these cases.

As a final obstacle, the HoH or AoH or whatever-of-whichever--the hash that "reads" the others--proposed would have to be declared inside the sub, after the variables $row and $val get their passed-in values. Question: would 94 "creations" of this 94-element data structure take more or less time than the same number of passages through the for-do loop? And how would I handle the six odd-balls mentioned above? Leave them out of the structure and process them separately maybe? Suggestions, thoughts or advice?

Thanks,

Deane
I and the poster read enough of your abbreviated code to get the
gest of what you seemed to do
... determine which hash to read and extract a value
 
we apparently both missed that in some instances youmight to just execute some code segment
 
so we both suggested using either a array of hashes or an hash of hashes since we it would
more efficient than using a for loop. It could be coded into lines and possibly one-liner
if you don't mind obscure code.
 
Now your abbreviated code had a line which read: $out = "N/A";
This indicated that it was possible that fr some value of $row a match would not found..
Hence my concern that a value of 101 would require 102 passes through the loop...not an endless loop.
 
Not being a guru, I had a preconcieved  notion of what "for ($row) " would do.
I suspected that Translate()  might not do want you expected it to do.
 
So I wrote a small test script to verify my suspision.
 
Here is the code:
#! perl
use warnings;
use strict;
 
sub Translate
{
  my ($row, $val) = @_;
 
  for ($row)
  {
     /^(5|6)$/o && do
     {
        print "$row - Will execute code segment A\n";
     };
      /^(2|4|7)$/o && do
     {
        print "$row - Will execute code segment B\n";
     };
     /^(0|1|3|8)$/o && do
     {
        print "$row - Will execute code segment C\n";
     };
  };
}
 

 my $string = "whatever";
 for (my $i = 0; $i <= 8; $i++)
 {
    Translate($i, $string);
 }
 
Here the output
 
0 - Will execute code segment C
1 - Will execute code segment C
2 - Will execute code segment B
3 - Will execute code segment C
4 - Will execute code segment B
5 - Will execute code segment A
6 - Will execute code segment A
7 - Will execute code segment B
8 - Will execute code segment C
 
From this I concluded that for any valid value of $row the "for ($ow)^ would execute just one pass
therefore:
    " last;" not necessary..."return $out;"  might be more appropriare if you really
    are concerned about preventing  tests that will not find a match
 
    no need for: $out = "N/A"; since you said that $row will always be valid
 
I suspect that you had a "if elsif else" code structure before using the "for" structure and found that a 3%
improvement. But is it a 3% improvement on code that cosumes a significant portion of of program or only
lets 1% percent.
 
Now It has been my experience that the way you write the code to be tested  either inline or
as an anoymous subroutine can give conflicting results  I have had code that when written
inline Code A was faster than Code B and then when the code segments
were writen as anonymous subroutine then Code A was slower than Code B.
 
Now I suggest that before you worry about peaking the performance your code that
1. complete the program, test it thoroughly.
2 if ir runs fast enough then let well enough alone
3 if it sluggish then use the profiler to find where the bottle neck eists
4 concentrate on the code srgment that is slow
   simplify the code ..the less it has to do the faster it will run
 
   it you find that you have to make the code more complex than it becomes harder to maintain
 
5. dont bother to worry about using 'o' unless you really really really not extact the last bit of
    bit of performance  ... most likely it will be a waste of your time
    Who cares if a script is faster by 1 millisecond or even 10 milliseconds
 
 

 
 
 
 
 
 
 
 



"renard" <[EMAIL PROTECTED]>

09/12/2005 18:25

       
        To:        <[EMAIL PROTECTED]>, <[email protected]>
        cc:        
        Subject:        Re: regexp /o in a sub



 
----- Original Message -----
From: [EMAIL PROTECTED]
To: [email protected]
Sent: Monday, September 12, 2005 1:48 PM
Subject: regexp /o in a sub


Wizards,


Here's one for you. I'm doing some optimizing on a script (using timethese and cmpthese calls in stub programs) and I was wondering about this. I know the compile-once option on regular expressions has been maligned, but I've found that it gets me about a 3% increase on one piece of code that uses a for loop with regexps as a pseudo-switch statement (just like in the Camel book). Here's what I'm working on (somewhat abbreviated):


sub Translate

{

my ($row, $val) = @_;


  my $out = "";


  for ($row)

  {

     /^(5|6|23|24|25|26|39|40|41|45|46|51|52|53|54|55|56|60|61|63|69|70|71|72|74|76)$/o && do

     {

        $out = $hashA( $val ) };

        last;

     };

     /^(11|12|13|14|22|28|32|44|50|58|62|64|65|73|75|82|83|85|86|91|92|93)$/o && do

     {

        $out = $hashB{$val};

        last;

     };

     /^(0|2|7|8|9|27|31)$/o && do

     {

        $out = $val;

        last;

     };

     /^(42|43|47|48|49|84)$/o && do

     {

        $out = $hashC{$val};

        last;

      };

     # ...


     /^(57)$/o && do

     {

        $out = $hashP{$val};

        last;

     };


     /^(59)$/o && do

     {

        $out = $hashQ{$val};

        last;

     };


     /^(81)$/o && do

     {

        $out = $hashR{$val};

        last;

     };


  } # end for ($row)


  $out = (length( $out ) > 0) ? $out : "N/A";   # Default value for nulls


  return( $row, $out );


} # sub Translate()


All the sub does is "translate" input to output using different hashes depending on the index passed into the for loop.


There are 18 of these "switch" cases, running from one to 26 OR-ed possibilities in the various cases. BUT, this code is inside a subroutine, so here's the question: does using the /o on these regexps inside a subroutine gain anything in runtime, as opposed to using it in mainline code? What if the script is compiled, using perlapp, into an executable? Is there any gain with /o then (either in mainline code or in a sub) or does any gain go out the window once the code's compiled? If it matters, the sub will get called 94 times per run of the script.


Thanks!

I am not a guru but the algorithm appears to be less than optinum.
 
Of cours if is difficult to truly judge it since the overall schme is not described
 
To me you seem to say that you to:
  use $row to determine which hash to use to obtain  the value from thst hash using the passed $value as a key
 
1.  you are trying to do 2 thing at one time.
 
     Perhaps you should consider creating an array of hashes rather the a set of hashes
 
     Now if the $row matches none of the values in your regex ... 99 then you will loop
through 99 times rather than exiting after one pass
 
Now my approach would be to do it in 2 steps.
 
Use hash where
     the rows are the keys and values are the indexes of the AoH
 
1   a one-liner can be written to to obtain an index into the AoH
 
2.  a one-liner can be written to use  the index and the $value (really a key) to obtain
    your $out
 
Occam's Razor says that probably this is the better solotion
 
Use the KISS principle   Keep It Simple, I am Stupid
 
 


Deane


P.S.: Yes, I *do* have way too much time on my hands.... Why else would I be going after such niggling improvements?   ;->


_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to