Cody Pendant has asked for the wisdom of the Perl Monks concerning the following question:

I'm wondering what's the best way to go about putting out some quite complex HTML pages from SQL selects.

It's all working, but it's working like this:

<pseudocode> output headers; output top of page; print '<ul>'; while fetchrow_hashref{ print '<li> stuff </li>'; } print '</ul>'; </pseudocode>

So would it be better to do this:

<pseudocode> output headers; output top of page; $list = '<ul>'; while fetchrow_hashref{ $list .= '<li> stuff </li>'; } $list .= '</ul>'; print $list; </pseudocode>

That is, to assemble big-ass string variables and dump them in their entirety in one print statement?

And I know what you're going to say, I should use HTML::Template. I will -- but the question above prompts me to say that using HTML::Template, you're pretty much only doing that second version i.e. all the page assembly happens, then the print, in HTML::Template -- right?

If I'm conscious of the users sitting looking at a blank page for a while, my instinct is to unbuffer output and do it more like the while() version above.

That way they get a sense of progress, even if it's slow.

Is the efficiency of 'assemble, then print' so much greater than 'print while'?

I'd be interested in your thoughts.



($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss') =~y~b-v~a-z~s; print

Replies are listed 'Best First'.
Re: Output HTML while(), or add to string while(), then output?
by BUU (Prior) on Aug 27, 2003 at 00:32 UTC
    I think the general response is that the it takes to communicate with your users is so much greater then the time it (should) take to read from the databases that any (small) delays in the script are neglible, and that any slowdown (If there is any!) from using HTML::Template is more then made up by the ease of writing/designing/maintaining the script.
Re: Output HTML while(), or add to string while(), then output?
by antirice (Priest) on Aug 27, 2003 at 01:47 UTC

    HTML::Template actually can do it either way. The benefit of building the output in a variable as you go along is that if you detect some sort of error, you can display an appropriate error page since you haven't sent anything to the browser yet. The benefit of printing straight out to the browser is that it requires less memory. Of course, with HTML::Template, you usually build your variables before associating them with the template so you could actually do your error checking there.

    In HTML::Template, you can print straight out to the browser using $template->output(print_to => *STDIN). Note that TMPL_LOOPs are actually built into a variable prior to being dumped out regardless. If you want TMPL_LOOPs to dump straight out, I actually covered this in a meditation, among other things.

    Hope this helps.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

Re: Output HTML while(), or add to string while(), then output?
by jdtoronto (Prior) on Aug 27, 2003 at 01:35 UTC
    Thats pretty much it really. Building the 'big-ass' string allows you to handle errors and exceptions somewhat more easily but the truth of the matter is that if the application is anything more than trivial the why aren't you using HTML::Template? If you are spending that much time getting the data then you better look at your database design and the fetching process.

    But of course I am a great advocate of the 'separationist' school of CGI writers.

    Processing is processing and presentation is presentation, they don't mix well!

    jdtoronto

Re: Output HTML while(), or add to string while(), then output?
by jeffa (Bishop) on Aug 27, 2003 at 12:19 UTC
Re: Output HTML while(), or add to string while(), then output?
by dragonchild (Archbishop) on Aug 27, 2003 at 13:12 UTC
    This actually points to a deeper issue, which is premature optimization. Are you truly conscious of the users sitting, looking at a blank page for a while? Or, are you thinking that there could be a problem and want to head it off at the pass? Remember, WWW users are really forgiving, especially if the page will be doing a lot of looking-things-up for them. Any page that loads in under 5 seconds is considered standard. If it consistently loads in under 1-2 seconds, then that's spectacular. (Orbitz and Google come to mind.) Anything over 5 seconds runs the risk of losing their attention. (Flash pages are a big culprit in this category.)

    If you are, then have you profiled the entire request, looking for the spot that takes the longest? In 99.999% of the cases where I have had to optimize a CGI request, the culprit has always been either the SQL statement or my handling of the result. Very simple optimizations that provide anywhere from 10%-50% speedup include:

    • Using prepare_cached() for inner selects
    • Unrolling loops from Perl into SQL
    • Moving decision points to SQL, reducing the size of the result set
    • Using bind_columns() and fetch() (just like DBI suggests ... fetchrow_hashref() is one of the slower ways to get your result set ...)

    Also, regarding buffered output to CGI ... you want your output to be buffered. In fact, you (almost always) never want anything to be sent to the user until you have the entire page assembled. Think about it this way - if you send half the page, then hit an error, you now have a user who thinks your site is stupid, cause it only gave it half the page. However, if you wait until you know the entire page, you can display only that which you want the users to see.

    Remember - most programming is (should be?) about handling error conditions. Most displays that are built (should?) have to do with error conditions. Users want to know when something went wrong. They don't want to be lulled into a false sense of security. Think about it this way - if your online banking site didn't tell you when a scheduled payment couldn't go through (for whatever reason), you'd be pretty pissed, right? (I have run into that one ...)

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.