in reply to Speeding up a mailing list script

As has been noted before, you should be using CGI. I realize that the form-handling code that you are using is very common, but it is also very broken. I'm particularly curious about this line:

$value =~ s/%0D%0A/|/g;

That says "take every cntl-M, followed by a cntl-J and change that combination to a pipe." I have no idea what's going on with that.

It should be noted that it's very easy to have whopping security holes with mail programs. You might want to check out STAMP (Secure, Template-Aware Mail Program) by btrott.

Two quick speed tips which should help tremendously. One, you appear to be iterating over a list and then opening the mail program in every iteration. If you keep using the mail program, see if you can move the open statement outside of the iteration. Iterating over a huge list and re-opening that every time will slow things down tremendously.

The other thing I would do is switch to HERE documents. You'll find them much faster. With a HERE doc, you specify a label and tell Perl to print until it encounters that label. Here's the basic syntax:

print <<"END_HERE_DOC"; This will be printed END_HERE_DOC

A couple of things to note about HERE docs: The closing label must be on the line by itself with no semi-colon (I can't tell you how many times I've added the semi-colon by accident). There should also be a return after the HERE document or Perl can't tell where it ends (note: that's only going to happen if the label is at the end of the file).

Here's a quick benchmark I whipped up to show the performance increase between multiple print statements and HERE documents.

use strict; use Benchmark; open NUL, "> nul" or die "Cannot open nul: $!"; for ( 1 .. 4 ) { test_em(); } sub test_em { timethese (5000000, { 'print' => 'print NUL "This is one line.\n"; print NUL "This is another line\n"; print NUL "Still printing\n"; print NUL "And printing and printing\n"; print NUL "Like the stupid Battery Bunny...\n";', 'here docs' => 'print NUL <<END_HERE; This is one line. This is another line Still printing And printing and printing Like the stupid Battery Bunny... END_HERE ' } ); }

We're printing to NUL to avoid having this print to the screen (thanks for that tip, tye).

Here's the output:

Benchmark: timing 5000000 iterations of here docs, print... here docs: 21 wallclock secs (19.04 usr + 0.95 sys = 19.99 CPU) @ 25 +0150.09/s (n=5000000) print: 44 wallclock secs (40.69 usr + 1.26 sys = 41.95 CPU) @ 11 +9189.51/s (n=5000000) Benchmark: timing 5000000 iterations of here docs, print...

As you can see from this limited example, the HERE document is over twice as fast as the print statements. I imagine you'll experience even greater performance benefits.

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.