Profiling and Benchmarking for Faster Startup Time

Our App had grown to a point where it was taking about 45 seconds from executing myapp_server.pl until it was ready to connect, so we decided it was time to pick the App apart and see what was slowing down startup time.

Tools:

The first step was to attempt to profile the app. However, the app is persistent, and most profilers are built for scripts that terminate, so an 'exit' statement was placed at the bottom of script/myapp_server.pl (right before App->run) so the script was isolated to starting up the App and not actually running it persistently.

then the profiler was run with

$ perl -Ilib -d:NYTProf script/myapp_server.pl #run the script and exit
$ nytprofhtml #parse output to html

After browsing through the result, the main culprit seemed to be Text::Balanced, with over 4 million calls,27 seconds total. Grepping around the modules the App was using, Data::Dumper::Simple mentioned using it in it's docs, which was included in a few of the App's controllers for debugging purposes.

Localized Catalyst/Utils.pm (put it in lib/Catalyst). added benchmarkers inside Utils->ensure_class_loaded

sub ensure_class_loaded {
    my $class = shift;
    my $opts  = shift;
    croak "Malformed class Name $class"
        if $class =~ m/(?:\b\:\b|\:{3,})/;
    croak "Malformed class Name $class"
        if $class =~ m//;
    croak "ensure_class_loaded should be given a classname, not a filename ($class)"
        if $class =~ m/\.pm$/;
    $t0 = new Benchmark;
    return if !$opts->{ ignore_loaded }
    && Class::Inspector->loaded( $class ); # if a symbol entry exists we don't load gain
 #this hack is so we don't overwrite $@ if the load did not generate an error
        my $error;
    {
        local $@;
        my $file = $class . '.pm';
        $file =~ s{::}{/}g;
        eval { CORE::require($file) };
        $error = $@;
    }
    $t1 = new Benchmark;
    $td = timediff($t1, $t0);
    warn "$class took: ",timestr($td) , "\t";
    die $error if $error;
    die "require $class was successful but the package is not defined"
        unless Class::Inspector->loaded($class);
    return 1;
}

This will warn how long it too to 'require' each class loaded.

My tags:
 
Popular tags:
 
Powered by Catalyst
Powered by MojoMojo Hosted by Shadowcat - Managed by Nordaaker