Faster way to execute contents of a perl script?

B

Brandon Hoppe

Hi,

I'm trying to find a faster way to do this. Right now I have a perl script that contains
function definitions. I have second perl script that contains calls to these functions.

Now the first perl script will execute the second perl script hundreds of times, in order
to call these functions.

So I have a loop that repeatadly changes global variables and then executes the second
perl script with a do $file; call.

This works and all, but its not very fast. It takes about 1 1/2 seconds to execute the
second script, so over hundreds of runs, you can see why it takes forever.

I was wondering if there's a faster way to repeatedly re-call all these functions. Like
reading the second script into an array and then "executing" the array. I doubt this is
possible but I was thinking something along this line, to get the file into memory to
execute over and over again which should be faster than to be reading from disk everytime.

Brandon
 
W

Walter Roberson

:I'm trying to find a faster way to do this. Right now I have a perl script that contains
:function definitions. I have second perl script that contains calls to these functions.

:Now the first perl script will execute the second perl script hundreds of times, in order
:to call these functions.

:So I have a loop that repeatadly changes global variables and then executes the second
:perl script with a do $file; call.

Don't do that. Use 'use' instead to bring the functionality in once, and then
just call upon the routines at need. Don't worry, the global variable values that
will be picked up will be those at execution time, not those at compile time.

Read the documentation on 'use'; also I suggest you might as well go as far as
formatting it into a "module" -- perldoc perlmod
 
B

Brandon Hoppe

Jim said:
There is no need to repeatedly 'do' the second file containing
subroutines. After this has been done once, the subroutines may be
called multiple times by name. Just make sure all of the code you wish
to execute is really in a subroutine and not on the main branch in the
second file.

The second file doesn't contain the subroutines, it contains CALLS to the subroutines.
That's why I have to keep 'do'ing the second file so that it calls the subroutines for me.
 
B

Brandon Hoppe

Walter said:
:I'm trying to find a faster way to do this. Right now I have a perl script that contains
:function definitions. I have second perl script that contains calls to these functions.

:Now the first perl script will execute the second perl script hundreds of times, in order
:to call these functions.

:So I have a loop that repeatadly changes global variables and then executes the second
:perl script with a do $file; call.

Don't do that. Use 'use' instead to bring the functionality in once, and then
just call upon the routines at need. Don't worry, the global variable values that
will be picked up will be those at execution time, not those at compile time.

Read the documentation on 'use'; also I suggest you might as well go as far as
formatting it into a "module" -- perldoc perlmod

Perhaps an example will help to visualize the problem:

#MAIN PERL SCRIPT
#!/usr/local/perl

while(<INPUT>) {
# read some value from INPUT
$VALUE = $_;

do "file.pl";
}

sub function1 {
# do something
}

sub function2 {
# do something
}


#FILE.PL SCRIPT
if($VALUE eq "A") {
&function1(34, 44, 33);
&function2(22, 33, 44);
}
if($VALUE eq "B") {
&function1(34, 44, 33);
&function2(22, 33, 44);
}


As you can see, the main perl script has the subroutine definitions. Now based on some
logic, the main script will execute either scriptA or scriptB, which just has calls to the
subroutines.

Scripts A and B are used elsewhere in another flow, so I don't want to modify these files
or compile them since that would change their behavior. This main perl script is a QUALITY
CONTROL script that verifies that Scripts A and B have valid data.

I hope I've given enough information as to what I'm needing to do.
 
W

Walter Roberson

:As you can see, the main perl script has the subroutine definitions. Now based on some
:logic, the main script will execute either scriptA or scriptB, which just has calls to the
:subroutines.

:Scripts A and B are used elsewhere in another flow, so I don't want to modify these files
:eek:r compile them since that would change their behavior.

I'm not sure why you say that compiling them would change their behaviour?

Perhaps you could proceed as follows:

sub make_sub($$) {
my ($subname, $filename) = @_;
open( SUB, $filename ) or die "Cannot find subroutine file $filename\n";
local $\;
$subfilecontent = <SUB>;
close( SUB );
eval "sub $subname() { $subfilecontent }";
}


This creates a subroutine on the fly that is does whatever the
given file would do, by importing the content of that file.
 
B

Brandon Hoppe

Walter said:
:As you can see, the main perl script has the subroutine definitions. Now based on some
:logic, the main script will execute either scriptA or scriptB, which just has calls to the
:subroutines.

:Scripts A and B are used elsewhere in another flow, so I don't want to modify these files
:eek:r compile them since that would change their behavior.

I'm not sure why you say that compiling them would change their behaviour?

Perhaps you could proceed as follows:

sub make_sub($$) {
my ($subname, $filename) = @_;
open( SUB, $filename ) or die "Cannot find subroutine file $filename\n";
local $\;
$subfilecontent = <SUB>;
close( SUB );
eval "sub $subname() { $subfilecontent }";
}


This creates a subroutine on the fly that is does whatever the
given file would do, by importing the content of that file.

Bingo! I was trying to do this earlier but couldn't figure out how to create a new
subroutine to include everything in the subfile.

Only thing is that I had to change this line:

$subfilecontent = <SUB>;

to

@subfilecontent = <SUB>;

Thanks!
 
W

Walter Roberson

:sub make_sub($$) {
: my ($subname, $filename) = @_;
: open( SUB, $filename ) or die "Cannot find subroutine file $filename\n";
: local $\;

That should be local $/; instead.

: $subfilecontent = <SUB>;
: close( SUB );
: eval "sub $subname() { $subfilecontent }";
:}
 
B

Brian McCauley

Walter said:
:As you can see, the main perl script has the subroutine definitions. Now based on some
:logic, the main script will execute either scriptA or scriptB, which just has calls to the
:subroutines.

:Scripts A and B are used elsewhere in another flow, so I don't want to modify these files
:eek:r compile them since that would change their behavior.

I'm not sure why you say that compiling them would change their behaviour?

Perhaps you could proceed as follows:

sub make_sub($$) {
my ($subname, $filename) = @_;
open( SUB, $filename ) or die "Cannot find subroutine file $filename\n";
local $\;
$subfilecontent = <SUB>;
close( SUB );
eval "sub $subname() { $subfilecontent }";
}


This creates a subroutine on the fly that is does whatever the
given file would do, by importing the content of that file.

Be aware that this approach will do odd things if the script has global
variables (either package scoped or file scoped lexicals).

The first step to aleviate this is to do as Apache::Registry does and
compile each such subroutine script in it's own package. You also
probably want at least some ruimentary error reporting.

eval "sub $subname() { package MyImportedScripts::$subname;\n#line 1
\"$filename\"\n $subfilecontent }; 1" or die $@;

(Obiously MyImportedScripts should really be a subpackage of a package
namespace your application already defines).

There are still remaining issues - such as the 'will not remain shared '
problem. (See entry in perldiag for explaination).
 

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,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top