Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^7: appending to html at beginning (don't use CGI.pm)

by haukex (Archbishop)
on Feb 03, 2017 at 18:49 UTC ( [id://1181006]=note: print w/replies, xml ) Need Help??


in reply to Re^6: appending to html at beginning (don't use CGI.pm)
in thread appending to html at beginning

Hi hippo,

Also, it is not the case that CGI.pm is the only pure CGI game in town.

That's a very good point, and I updated my node accordingly.

... and will be much faster to run in a traditional CGI environment

If you mean speed-wise, you may be right, but if you mean how quickly one can get up and running, I think Plack::Handler::CGI makes that relatively easy:

#!/usr/bin/env plackup use warnings; use strict; use Plack::Request (); my $app = sub { my $req = Plack::Request->new(shift); # access params via e.g. $req->parameters->{...} ...

Regards,
-- Hauke D

Replies are listed 'Best First'.
Re^8: appending to html at beginning (don't use CGI.pm)
by hippo (Archbishop) on Feb 04, 2017 at 11:34 UTC
    If you mean speed-wise, you may be right

    I do and I am. :-)

    About a year ago a new project was starting and it was unclear at that point whether it would be better as a traditional CGI system or using some sort of persistent back-end. Having read of the joys of Plack this sounded to me like an ideal use for it - code the system with Plack and we could switch seamlessly between normal CGI and a persistent application.

    Obviously the first thing to do was to put together a prototype to prove the concept. I wrote a little "hello world" script using Plack (it may even have been lifted directly from the docs) and managed to get it running without much bother as a persistent job. Then I switched over the front end and had it running as traditional CGI. That's when I noticed the speed issue.

    We all expect a CGI script to be slower than a persistent system (that's why there's an F in FCGI after all) but this was noticeably slower. And it seemed to me to be a lot slower than many of the other CGI scripts I would normally use. And it wasn't even doing anything other than respond with "Hello World".

    So I did the natural thing and benchmarked it as a traditional CGI both with Plack and without. It turned out that using Plack slowed down the traditional CGI by about a factor of 6.

    It was decided that this was just too much of a penalty so instead of using Plack I wrote a frontend which had a very simple loading routine that could be called either from CGI or from an FCGI implementation. This added no measurable difference to the execution time of the plain CGIs and meant that we could easily switch between the two approaches as the need arose.

    TL;DR: Plack is a nice idea but while it technically can be used for traditional CGI scripts beware that the penalty is a big slowdown.

      A factor of 6 sounds like a broken benchmark. A plack wrapper is not doing so much that much that it makes sense it would be 600% slower. Though perhaps there is something wonky/unexpected in the CGI handler. Do you have your benchmark on github or someplace to share?

        I couldn't find the original scripts (it was a good while ago and the point was proven then) so I've knocked up these scripts today which follow the same principle. If you can point out the errors in what I've done that would be most helpful.

        Firstly, here's the trivial non-plack CGI:

        #!/usr/bin/perl use strict; use warnings; use CGI::Lite; my $cgi = CGI::Lite->new; $cgi->parse_form_data; print "Content-Type: text/plain\n\n"; $cgi->print_data; exit;

        Here's the equivalent PSGI:

        use strict; use warnings; use Plack::Request; my $app = sub { my $env = shift; my $req = Plack::Request->new($env); my %params = %{$req->parameters}; my $body = ''; while (my ($k, $v) = each %params) { $body .= "$k = $v\n"; } my $res = $req->new_response; $res->status (200); $res->headers ({ 'Content-Type' => 'text/plain' }); $res->body ($body); $res->finalize; }

        And finally the wrapper to turn the PSGI into a CGI:

        #!/usr/bin/perl use strict; use warnings; use Plack::Loader; my $app = Plack::Util::load_psgi("light.psgi"); Plack::Loader->auto->run($app);

        To turn this into a "real" test I've run these through Apache with both client and server on the same host (ie. no network issues). The 2 cgi scripts were called with a single key-value pair in the query string (foo=bar, since you ask) and produced the same content as a result. Each script was called 11 times (1 as PoC and then another 10)

        The timings come from the apache log (with %D) and are as follows (all values are microseconds).

        Normal CGICGI through Plack
        Maximum2137193761
        Minimum1249480521
        Mean1499986481

        So, looking at the mean request time the plack version is 5.77 times slower than the plain CGI.

        Now, these are small samples and are wallclock times so YMMV and I encourage you to re-run the tests on your own platforms to see how they compare but this crude example reflects pretty closely what I originally saw and is enough of a penalty to be avoided (for me).

      Hi hippo,

      Thanks very much for the info, that's good to know! If it wasn't obvious yet, I haven't used Plack in a traditional CGI environment very much :-) I try to use persistent processes as much as I can nowadays.

      Regards,
      -- Hauke D

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1181006]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2026-01-17 10:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What's your view on AI coding assistants?





    Results (121 votes). Check out past polls.

    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.