code optimization and readability 
Author Message
 code optimization and readability

Quote:

> before i post the links to the file, i'd like to first apologize for the
> length of this, it was not my intention to make it as long winded as it
> turned out. secondly, the html page generated will not show proper code
> spacing due to not being a fixed width font (unless you have that over
> ridden in your browser of course). so i have two links, the first is the
> html page with syntax highlighted (thank gvim for including this handy
> feature), and the second is a plain text file for those who don't
> need/want the syntax highlighting and would prefer the text file due to it
> being more commonly displayed with a fixed with font.

> http://www.*-*-*.com/
> http://www.*-*-*.com/

> (sorry for the hell you're about to endure if you choose to look at the
> code)

First recommendation: toss the idea of reinventing wheels.  There are a
number of good templating systems in Perl already - Text::Template,
HTML::Template, etc.  Many of these already have decent to superb
optimisations in them.  For example, H::T can use shared memory to store
pre-parsed templates, or a file cache of them.  T::T probably does
something similar.

The next thing is the way you interact with the http server.  Try using
something that simplifies this.  For example, CGI::Application.  It makes
much of this job easier.


A lot more clear.

Rather than reading a config file ... use one of the modules that reads
config files.

This should help remove most of your code, which means that your code will
be more flexible.



Wed, 19 Oct 2005 21:02:37 GMT  
 code optimization and readability
Also sprach Chris H.:

[...]

Quote:
> so with all that said (sorry), i come here. looking for some help/tips/etc
> on how to improve this behemoth. basically what i am looking for are better
> ways to do things, but also looking for tips on how to improve the
> readability of the code. in the past its always been functionality over
> readability, this time i want both. i'm looking for that elusive "uber"
> codebase that when opened by someone who doesn't even know perl to say, "ya
> know, i don't understand what this is doing but its {*filter*} as hell. when i
> learn perl, i'd like for my code to turn out like this." rather improbable,
> but not impossible. i know there are always tradeoffs when dealing with
> this topic, which even more questions stem such as, "should i use this, or
> should i use that? hrm..."

I didn't have a more in-depth look into your code but some things are a
little clumsy and costly in terms of CPU-cycles than they could be.
First of all, something like this:

     sub print_news_tmpl {

        my $news_date    = $_[0];
        my $news_time    = $_[1];
        my $news_author  = $_[2];
        my $news_content = $_[3];
        my $news_title   = $_[4];
        my $news_aemail  = $_[5];
        ...
     }

This is lot to type and slower than simply writing:

    sub print_news_tmpl {
        my ($news_date, $news_time, $news_author,


        ...
    }

According to Benchmark.pm this saves about 20%.

Then you are doing some redundant checks (I think):

 if(%cookie) {
    if($cookie{dpcookie}) {
        $dpcookie = $cookie{dpcookie}->value;
        $dpcookie = pack("H*", $dpcookie);
        ($cuname, $cupass, $cutype) = split(/;/, $dpcookie);
        &verify_cookie_data($cuname, $cupass);
        $logged_in = 1;
    }
 }

 # set theme to default unless logged in
 my $theme_name = "default";

 if ($logged_in == 1) {

    ...
 }

If I read the above correctly you can save at least two if-conditions:

    my $theme_name = "default";

    if ($cookie{dpcookie}) {
        $dpcookie = $cookie{dpcookie}->value;
        $dpcookie = pack("H*", $dpcookie);
        ($cuname, $cupass, $cutype) = split(/;/, $dpcookie);
        verify_cookie_data($cuname, $cupass);
        $logged_in = 1;
        ($theme_name) = db_query (...);
    }

The iterations over some files could be sped up, too. First rule is to
skip lines as early as possible, so:

    while (<CFG>) {
        next if /^[\s#]*$/;
        chomp;
        ...
    }

's/\n//g' is not a good way of removing newlines at the end of a string.
Use chomp() for that or - if you want to remove them unconditionally
from a string - 'tr/\n//d'.

The while-loop in parse_theme_config() could be done with a
dispatch-table:

    ...
    my %dispatch = (
        LinksDelimeter => sub {
            ($links_delimiter = $_[0]) =~ tr/s/ /;
        },
        SiteLinksDisplay => sub { ... },
        ...
    );
    while (<CFG>) {
        chomp;
        my ($key, $value) = /(.*?)=(.*)/;
        next if ! exists $dispatch{ $key };
        $dispatch{ $key }->($value);
    }

Had you used a hash for the several configuration keys it'd be even
easier and quicker:

    my %theme_config;

    sub parse_theme_config {
        ...
        while (<CFG>) {
            my ($key, $value) = /(.*?)=(.*?)/ or next;
            $theme_config{ $key } = $value;
        }
    }

I see a lot of such code that could be written more idiomatically and
thus would be more readable and quicker. Remember that Perl offers many
ways to do something. Employing conditional code for example can often
be reduced to one line or so (as shown in the snippet above).

Another thing that I would consider is using one of the many templating
modules available from the CPAN instead of rolling your own.

Also, keep an eye on database issues. Often a database is queried more
often than it would be necessary. Furthermore code like

    db_query ("select user_theme from users where uname = '$cuname'");

suggests that you may not be doing it properly. You are almost certainly
using DBI so remember that you can do

    my $sth  = $dbh->prepare("select user_theme from users where uname = ?");

    # now one of the fetch* methods
    my $data = $sth->fetchall_hashref($cuname);

Those were just a few random remarks. Others might observe different
things to improve.

Tassilo
--
{
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval



Wed, 19 Oct 2005 21:29:07 GMT  
 code optimization and readability


Quote:
>For example, H::T can use shared memory to store pre-parsed
>templates, or a file cache of them.  T::T probably does something
>similar.

Nope, nothing like that.  Premature optimization is the root of all
evil, and T::T is already fast.

One thing people often suggest is that T::T should take the code
fragments in the template and compile them into anonymous subroutines,
then call the anonymous subroutines, instead of using 'eval' every
time.  There's even a module on CPAN, with the rather obnoxious name
'Text::FastTemplate', which does this.  It seemed like a reasonable
thing to try, so I did some benchmarking, and found that it was indeed
sometimes faster than Text::Template---and often it was much slower.

If anyone with a real application finds that T::T is too slow and
wants to put in some work profiling it and make some recommendations,
I'd be really interested to see them.  But my experience with
'optimizations' is that if you don't make this large time investment,
you end up with something like Text::FastTemplate that promises to be
faster and isn't.

In the meantime, I haven't had any complaints, so I've left it alone.

Incidentally, I released V1.44 last week, which has some minor bug
fixes, test suite enhancements, and documentation improvements.



Thu, 20 Oct 2005 00:29:32 GMT  
 code optimization and readability

Quote:

> i decided that the direction i was going wasn't exactly optimized for
> several thousand hits/day (if i ever got that much). so i started a line
> by line "audit" of the code. using some tips from the good ol' camel
> book i proceeded to go through the scripts line by line seeing if i
> could write this line better or more efficient, or that block could be
> minimized to execute faster.

If performanc does becomes an issue, use mod_perl
(http://perl.apache.org).  This allows your script to be compiled once per
httpd process, instead of each time it's called by a user clicking on it,
dramtically decreasing runtime and CPU use.  From looking at your script,
it is neither a mod_perl module nor an Apache::Registry script. Some
modifications will be needed to run under mod_perl.  Mods needed for
running under Apache::Registry are typcially less.  In any event it can
increas server performance many times.

Also, note that several thousand hits a day is not that much.  Example:
8000 hits per day over an 8 hour day is 1/3 hit per second.

That being the case it is far more important to produce good maintainable
code than to try and inline things that modularity demands should be
left as functions.

So, the previous poster's suggestions about using avalable modules to
improve and simplify your code make sense.  Combined with mod_perl, your
code can be better AND faster.

----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---



Thu, 20 Oct 2005 00:52:26 GMT  
 code optimization and readability
thanks for all the tips guys, will be checking into it.

bob, sorry, i did forget to mention that this is running under mod_perl
already. its running via Apache::PerlRun instead of Registry. there is no
handler setup as they are all individual scripts, instead of being a main
module with various utility scripts. so while i may be getting some
benefit, im not getting it all. the next incarnation of this site will be
done under mod_perl properly.

thanks again
-chris h

Quote:

> If performanc does becomes an issue, use mod_perl
> (http://perl.apache.org).  This allows your script to be compiled once per
> httpd process, instead of each time it's called by a user clicking on it,
> dramtically decreasing runtime and CPU use.  From looking at your script,
> it is neither a mod_perl module nor an Apache::Registry script. Some
> modifications will be needed to run under mod_perl.  Mods needed for
> running under Apache::Registry are typcially less.  In any event it can
> increas server performance many times.

> Also, note that several thousand hits a day is not that much.  Example:
> 8000 hits per day over an 8 hour day is 1/3 hit per second.

> That being the case it is far more important to produce good maintainable
> code than to try and inline things that modularity demands should be
> left as functions.

> So, the previous poster's suggestions about using avalable modules to
> improve and simplify your code make sense.  Combined with mod_perl, your
> code can be better AND faster.



Thu, 20 Oct 2005 01:49:27 GMT  
 code optimization and readability

Quote:



>>For example, H::T can use shared memory to store pre-parsed
>>templates, or a file cache of them.  T::T probably does something
>>similar.

> Nope, nothing like that.  Premature optimization is the root of all
> evil, and T::T is already fast.

Fair enough.  All my point was is that by letting someone else worry about
it, your code gets more maintainable.  And you can get speed benefits
simply by upgrading.  For example, an older version of CGI::Application
used a number of eval's where they weren't required.  I actually helped the
C::A author see this (and provided benchmarks to prove it), and anyone who
upgraded automatically got this speed boost.

If someone gave you a patch that provided T::T a 5% improvement in speed
without any significant degradation to readability, would you not take the
patch?  The OP, if he used T::T, would be able to upgrade and get that 5%
boost without any real effort - it's an effort someone else has expended
already.  Rather than reinventing that wheel, including its optimisations.

Quote:
> One thing people often suggest is that T::T should take the code
> fragments in the template and compile them into anonymous subroutines,
> then call the anonymous subroutines, instead of using 'eval' every
> time.  There's even a module on CPAN, with the rather obnoxious name
> 'Text::FastTemplate', which does this.  It seemed like a reasonable
> thing to try, so I did some benchmarking, and found that it was indeed
> sometimes faster than Text::Template---and often it was much slower.

I like the way that H::T precompiles the HTML text, and then caches that
precompiled version in memory in such a way that multiple processes can
take advantage of it (shared memory or disk cache).

That said, if I were to use T::T (which I'm considering), it wouldn't be for
HTML stuff anyway, so that type of caching would not be important to me.  
In fact, the less steps between template and output, the better for that
application.

Quote:
> If anyone with a real application finds that T::T is too slow and
> wants to put in some work profiling it and make some recommendations,
> I'd be really interested to see them.  But my experience with
> 'optimizations' is that if you don't make this large time investment,
> you end up with something like Text::FastTemplate that promises to be
> faster and isn't.

> In the meantime, I haven't had any complaints, so I've left it alone.

Isn't that the idea of reusable code?  Solve it once, and, barring a better
solution, leave well enough alone.  :-)
Quote:
> Incidentally, I released V1.44 last week, which has some minor bug
> fixes, test suite enhancements, and documentation improvements.



Thu, 20 Oct 2005 03:14:00 GMT  
 code optimization and readability
welp, i updated the code at the links i provided...its getting a lot better,
but still so much left to do. hoping perhaps i can get it trimmed down,
then turned into a module and preload it under mod_perl so i can benefit
from both mod_perls module cache, but also H::T's. i turned on caching for
one of the calls, but im not really sure if its using it or not right now.

dont know why i havent used H::T until now, but i appreciate you guys giving
me the info, i picked it up in literally no time. its syntax hilariously
easy to absorb, and it trimmed quite a lot of code from my template.pl
script thus far. now all thats left is to finish what i started...

-chris h.



Thu, 20 Oct 2005 15:13:49 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Optimization of Perl code

2. Optimization of the code - suggestions?

3. Code optimization request and i18n issues

4. Code Optimization-- Can I do this better?

5. Code Optimization-- Can I do this better?

6. Code optimization: Anyone got a few spare minutes?

7. Optimization of date calculation code

8. Readability & Languages HOWTO

9. How to enclose scalar for readability?

10. Three cheers for the readability of c.l.p.misc

11. possible perl optimizations

12. optimization help

 

 
Powered by phpBB® Forum Software