$self->stash() on go slow from ver 4.84 onwards

40 views
Skip to first unread message

Peter Robb

unread,
Jul 30, 2014, 6:51:01 PM7/30/14
to mojol...@googlegroups.com
I have been working on a Lite app in ver 4.53 for some while and after an upgrade to ver 5.21 I noticed a distinct slowdown in page rendering.

I have tracked it back to a snippet that loads a few thousand stash values.

Under ver 4.83 or 4.53 it takes less than a second, while from ver 4.84 onwards it takes just over 3 seconds..

Some test code..

#!/usr/bin/env perl

use utf8;
use Mojolicious::Lite;
use DBI;

my $match = $ARGV[0] || die "No database number\n";

my $dbh = DBI->connect("dbi:SQLite:$match.db", undef, undef, {sqlite_unicode => 1});

helper db => sub { $dbh };

get '/' => sub {
        my $self = shift;
my @rows;
        my $sth = $self->db->prepare('SELECT * FROM updates');
        $sth->execute;
        while (my $t_id = $sth->fetchrow_hashref() ) {
push(@rows, ($$t_id{'id'}, $$t_id{'content'}));
        }
while (my $id = shift(@rows)) {
my $content = shift(@rows);
$self->stash($id => $content);
}
        $self->render('invalid');
};

app->start;

__DATA__

@@ invalid.html.ep

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>combien.info LiveScore</title>
</head>
<body>
<center><h2>Invalid Data Format...</h2>
<p>
<h3><%= $sponsor %> &nbsp; <%= $g16a %></h3></center>
</body>
</html>

Log output from    morbo tst.pl ls0   using ver 4.84

[Thu Jul 31 00:42:37 2014] [info] Listening at "http://*:3000".
[Thu Jul 31 00:42:54 2014] [debug] Your secret passphrase needs to be changed!!!
[Thu Jul 31 00:42:54 2014] [debug] GET "/".
[Thu Jul 31 00:42:54 2014] [debug] Routing to a callback.
[Thu Jul 31 00:42:54 2014] [info] selected * from updates..
[Thu Jul 31 00:42:54 2014] [info] pushed * to @rows..3720
[Thu Jul 31 00:42:57 2014] [info] stashed * from @rows..
[Thu Jul 31 00:42:57 2014] [debug] Rendering template "invalid.html.ep" from DATA section.
[Thu Jul 31 00:42:57 2014] [debug] 200 OK (3.024671s, 0.331/s).

[Thu Jul 31 00:43:08 2014] [debug] GET "/".
[Thu Jul 31 00:43:08 2014] [debug] Routing to a callback.
[Thu Jul 31 00:43:08 2014] [info] selected * from updates..
[Thu Jul 31 00:43:08 2014] [info] pushed * to @rows..3720
[Thu Jul 31 00:43:11 2014] [info] stashed * from @rows..
[Thu Jul 31 00:43:11 2014] [debug] Rendering cached template "invalid.html.ep" from DATA section.
[Thu Jul 31 00:43:11 2014] [debug] 200 OK (3.008230s, 0.332/s).

Any ideas anyone?

Peter.

sri

unread,
Jul 30, 2014, 7:12:24 PM7/30/14
to mojol...@googlegroups.com

Peter Robb

unread,
Jul 30, 2014, 7:29:56 PM7/30/14
to mojol...@googlegroups.com

Aha...

Is the speed hit likely to be improved on?

Peter.

--
You received this message because you are subscribed to a topic in the Google Groups "Mojolicious" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mojolicious/KTGEl4GjKkU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mojolicious...@googlegroups.com.
To post to this group, send email to mojol...@googlegroups.com.
Visit this group at http://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

sri

unread,
Jul 30, 2014, 7:45:13 PM7/30/14
to mojol...@googlegroups.com

Is the speed hit likely to be improved on?


Dunno, thousands of method calls is generally not a smart thing to do, optimizing for it seems wrong.

--
sebastian 

sri

unread,
Jul 30, 2014, 8:00:15 PM7/30/14
to mojol...@googlegroups.com
Dunno, thousands of method calls is generally not a smart thing to do, optimizing for it seems wrong.

I am trying a few things that appear to improver overall performance though, more proposals along those lines would be welcome.


--
sebastian 

Peter Robb

unread,
Jul 31, 2014, 4:05:34 AM7/31/14
to mojol...@googlegroups.com

Wow !

Very nice changes.. :-)
And quick too.
Thanks.

Peter

--

Jan Henning Thorsen

unread,
Jul 31, 2014, 8:22:46 AM7/31/14
to mojol...@googlegroups.com
Maybe I'm mistaken, but I think you can make your code faster as well...
    
    get '/' => sub {
        my $self = shift;
        my $sth = $self->db->prepare('SELECT id, content FROM updates');
        my %data;

        $sth->execute;

        while (my $r = $sth->fetchrow_arrayref) {
$data{$r->[0]} = $r->[1];
        }

        $self->render('invalid', %data);
    };

1) fetchrow_arrayref() is faster than fetchrow_hashref(). And it works, since you know the position of the columns because of the modified SELECT statement.
2) You only loop once. Which is at least twice as fast.
3) You never call stash, but pass the %data directly on to render() instead.

A completely different thing is that the code doesn't do any error checking. I would suggest using https://metacpan.org/pod/DBI#RaiseError

On Thursday, July 31, 2014 10:05:34 AM UTC+2, Peter Robb wrote:

Wow !

Very nice changes.. :-)
And quick too.
Thanks.

Peter

On 31 Jul 2014 02:00, "sri" <kra...@googlemail.com> wrote:
Dunno, thousands of method calls is generally not a smart thing to do, optimizing for it seems wrong.

I am trying a few things that appear to improver overall performance though, more proposals along those lines would be welcome.


--
sebastian 

--
You received this message because you are subscribed to a topic in the Google Groups "Mojolicious" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mojolicious/KTGEl4GjKkU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mojolicious+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages