PerlEx FAQ

What is PerlEx?

Why are HTTP headers appearing in the browser body?

Why does my Server Side Include produce HTTP headers?

I can't get the samples to work, what should I do?

Can I set up a persistent data connection with PerlEx?

My script worked with perl.exe, but doesn't work with PerlEx, why?

Why don't my scripts that read from the DATA filehandle work?

I edited some of  my scripts and now they don't work, why?

When I run PerlEx, I'm not seeing any increase in speed. Why?

How can I check if PerlEx is running from within a script?

How do I optimize print() performance?

Why isn't my required file working properly?

Why do I have unwanted data persistence problems when using certain modules?

My scripts that use CGI.pm don't seem to work, why?

Are there UNIX versions of PerlEx?

Does PerlEx work well with all available CPAN modules?


What is PerlEx?

PerlEx is a web server plugin designed to work with your Windows web server to substantially increase the speed at which your Perl CGI programs are run by the server. PerlEx also enhances the functionality of Perl by adding features such as embedded scripts which are not present in similar products.

Why are HTTP headers appearing in the browser body?

If you see HTTP header information appearing in the body of a client browser that accesses scripts served by PerlEx, you should change the EnableCGIHeader registry entry to 0. The script will then be responsible for outputting all HTTP headers.

Why does my Server Side Include produce HTTP headers?

PerlEx does not distinguish between files which are served up in their entirety and files which are included. If you have EnableCGIHeader set to 1 in the registry, PerlEx will emit HTTP headers for each document which it serves.

If you use Server Side Includes in the documents that you are serving with PerlEx, turn off EnableCGIHeader in the registry, and provide your own HTTP headers for your documents.

I can't get any of the PerlEx examples to work, what should I do?

If the PerlEx example scripts won't run, check the following:

Can I set up a persistent data connection with PerlEx?

Yes. See the section on Persistent Connections in the documentation for more info.

My script worked with perl.exe, but doesn't work with PerlEx, why?

Try setting the Interpreters registry entry to 0. Some Perl programs may not be compatible with PerlEx, because they may not be initializing themselves correctly at startup.

You can isolate such scripts in a particular directory and specify an interpreter class for these scripts. Thus, other scripts that don't have this problem can continue to get the benefits of PerlEx.

Why don't my scripts that read from the DATA filehandle work?

PerlEx uses Perl's eval() operator to precompile scripts. This operator does not keep a reference to the source text in memory, since doing so would cause a memory leak. Since the DATA filehandle relies on the source text after the __END__ or __DATA__ tokens being available at run time, this does not work under PerlEx.

Note that __END__ and __DATA__ tokens in your scripts are harmless as long as your script either does not rely on the DATA filehandle, or knows how to deal with the DATA filehandle being unavailable.

You have two choices to deal with this issue:

  1. rewrite your script to not rely on the DATA filehandle
  2. move these scripts into a separate folder and add an interpreter class for this folder, and set the Interpreters entry to 0.

I edited some of my scripts and now they don't work, why?

PerlEx normally compares the file timestamp of a script with the time it was last compiled and reloads it if it has changed since the last time it was compiled.

However, this only works for scripts launched directly by PerlEx. If you change a script that has been referenced by a require or use statement, you will either have to stop and restart the server, or use the Reload function within the script for it to work properly.

When I run PerlEx, I'm not seeing any increase in speed. Why?

The first time PerlEx runs one of your scripts, it will always be slow, as it is precompiling them, but every time you run them after that, you should experience a noticeable increase in speed.

If the problem persists, check to make sure of the following:

  1. The Interpreters registry entry should not be set to 0. This entry should be set to 0 only within specific interpreter classes that are deliberately meant to not cache scripts that are at a particular location. Setting this entry in the default interpreter class (i.e. at the top level of PerlEx registry settings) will disable caching for all scripts run by PerlEx that don't match an interpreter class with an overriding setting.
  2. The script should not exit with a non-zero status, either by calling exit() with a non-zero argument, or by throwing an exception, for example, by calling die(). Under those circumstances, PerlEx will flush its cache for that script and recompile it during the subsequent request, resulting in the observed degradation in performance.
  3. The web server is properly configured to run the script under PerlEx. Make sure that ISAPI caching has not been disabled.

Setting the Trace registry entry can help debug some of these issues.

How can I check if PerlEx is running from within a script?

You can check if PerlEx is running from within a script by adding the following:

if (exists $ENV{'GATEWAY_INTERFACE'}
    and $ENV{'GATEWAY_INTERFACE'} eq "CGI-PerlEx")
{
    ...
}

This test actually indicates that the script has been cached by the PerlEx compiler. When scripts are running under PerlEx with no caching, i.e., the Interpreters registry entry is set to 0, this test will return false because PerlEx behaves just like regular CGI or Perl for ISAPI under this setting.

How do I optimize print() performance?

My script makes many calls to print, and PerlEx does not seem to be a lot faster than regular Perl CGI when running it. How do I optimize print() performance?

Outputting data is a relatively expensive operation, whether it is a regular Perl CGI script, or one running under PerlEx. While most scripts will not be affected to any significant degree by this fact, any Perl script that performs many calls to print will see an increase in speed by gathering as much data as possible before calling print. Perl makes this easy by providing the '.=' operator.

For example, if the following code:

$data = "Hello";
print $data;
$data = " world";
print $data;
$data = "\n";
print $data;

is rewritten as:

$data = "Hello";
$data .= " world";
$data .= "\n";
print $data;

it will execute faster, whether it is running with Perl or PerlEx.

An additional point to note is that PerlEx output is unbuffered--every print statement results in output from the web server. While this gives the programmer precise control over what gets sent from the web server, it also imposes a slight penalty on execution time when many print statements are used in a script.

Why isn't my file loaded with require working properly?

Example: A common file, C.plex, is included (via a require statement) by two other scripts, A.plex and B.plex. The first time either A.plex or B.plex is run, the script works, but then the other script won't run.

The problem here is a namespace issue. Once script C.plex is loaded by either script A.plex or by script B.plex, its data and subroutines become part of the calling script's namespace, if C.plex does not contain a namespace declaration.

The solution is to declare a namespace in C.plex using a package declaration. C.plex will look like this:

package C;
sub foo
{

[your code here...]

}

A.plex and B.plex need to access subroutines in package C by using the following syntax: 

C::foo(...); 

In general, it is good Perl programming practice to explicitly declare a namespace in any file that will be loaded by other scripts.

Why do I have unwanted data persistence problems when using certain modules?

Some modules on CPAN use global variables which will persist when using PerlEx. If you discover that this is the case, and if the module does not have a way for you to initialize its data, you may wish to add the scripts which use these modules to an interpreter class that has the Interpreters registry entry set to 0. This is known as running the script in "zero interpreter mode". Note that doing this will make PerlEx not precompile the script anymore, and therefore it will execute significantly slower.

My scripts that use CGI.pm don't seem to work, why?

If you use the CGI.pm package in your scripts, we recommend using CGI.pm version 2.56 or higher.

There are some specific issues to be aware of when using CGI.pm because global data is persistent across script invocations when running PerlEx. ActiveState works with the author of CGI.pm on an ongoing basis to ensure compatibility of PerlEx and CGI.pm.

You can avoid global data persistence problems by using the object interface. New CGI objects should be created like so:

my $cgi = CGI->new();

Thus, instead of this code:

use CGI qw/:standard/;
$aVariable = param('value');

you should create a CGI object:

use CGI qw/:standard/;
my $cgi = CGI::->new();
$aVariable = $cgi->param('value');

Do not create more than one CGI object in your scripts because when doing a POST, after the first CGI object is created, subsequently created CGI objects will not contain the posted data.

When using the functional interface to CGI.pm, you should call the following function before your script exits: 

CGI::initialize_globals();

This will make sure that CGI.pm initializes its internal global variables and handles future invocations of your script correctly. This function must be called regardless of the path of execution in your script, otherwise your script will work against the data from the previous invocation of the script.

The alternative to taking these precautions is to run the scripts at an Interpreters setting of 0, thereby losing the performance advantages of PerlEx caching.

Are there any Unix versions of PerlEx