Monday, December 7, 2009

Plack/PSGI performance

[Original Spanish source]
In my post about PSGI & Plack I said that it was fast, to demonstrate this I benchmarked the program running as CGI in Apache (ACGI) as a standalone server in CGI::Emulate::PSGI (CEP) and as a native PSGI application.

The test was very not rigorous, because I really just wanted to confirm what I've read.

The command to report the rate was:

$ ab -n 1000 -c 10 -k "http://localhost:5000/cgi-bin/perldocweb?pod=PSGI&format=source"

Which gave the following results:

ACGI
CEP
PSGI
Requests per second
10.57
267.17
512.31
Time per request (ms)
94.618
3.743
1.952
Transfer rate (kBps)
179.52
4539.79
8686.67

Just to see the raw speed, I made a small program to serve text files and compare the performance against Apache serving the same static files:

 1 #!/usr/bin/perl
 2 
 3 use Modern::Perl;
 4 use IO::File;
 5 
 6 my $dir = "/home/jrey/htdocs";
 7 
 8 my $app = sub {
 9     my $env      = shift;
10     my $filename = $dir . $env->{'REQUEST_URI'};
11     return [ '200', ['Content-Type' => "text/plain"], IO::File->new($filename) ];
12 };

The results for the command:

$ ab -n 1000 -c 10 -k "http://localhost:5000/PSGI.pod"

where:

Plackup
Apache
Requests per second
614.69
3217.03
Time per request (ms)
1.627
0.311
Transfer rate (kBps)
10425.21
55133.41

As I said, Plack is very fast, and in particular this test shows that the performance is acceptable even for static content, so we can deploy applications directly on perl, without additional Web server components, except for special needs such as high availability and load balancing, in which case there are some perl based solutions solutions as well, for example perlbal. Did I told you that there is PSGI for perlbal?

Sunday, December 6, 2009

CGI::Emulate::PSGI error

While working with the code of the previous article, I realized that the example of CGI::Emulate::PSGI wasn't working, because I did not reset CGI's global variables.
Here is the correct way to do it:

1 use CGI::Emulate::PSGI;
2 use CGI;
3 
4 my $app = CGI::Emulate::PSGI->handler(sub {
5     CGI::initialize_globals();
6     do "perldocweb";
7 })