]> Sergey Matveev's repositories - public-inbox.git/commitdiff
msgmap: speed up minmax with separate queries
authorEric Wong (Contractor, The Linux Foundation) <e@80x24.org>
Sat, 7 Apr 2018 03:41:54 +0000 (03:41 +0000)
committerEric Wong (Contractor, The Linux Foundation) <e@80x24.org>
Sat, 7 Apr 2018 03:42:30 +0000 (03:42 +0000)
This significantly improves the performance of the NNTP GROUP
command with 2.7 million messages from over 250ms to 700us.
SQLite is weird about this, but at least there's a way to
optimize it.

lib/PublicInbox/Msgmap.pm
t/perf-nntpd.t

index f5f88431bbfa82d1e7af847126d14441f6409864..feef8ba79ab9a657d8135b0c65ca0186dd7bed51 100644 (file)
@@ -138,10 +138,14 @@ sub num_for {
 sub minmax {
        my ($self) = @_;
        my $dbh = $self->{dbh};
 sub minmax {
        my ($self) = @_;
        my $dbh = $self->{dbh};
-       my $sth = $self->{num_minmax} ||=
-               $dbh->prepare('SELECT MIN(num),MAX(num) FROM msgmap');
+       # breaking MIN and MAX into separate queries speeds up from 250ms
+       # to around 700us with 2.7million messages.
+       my $sth = $dbh->prepare_cached('SELECT MIN(num) FROM msgmap', undef, 1);
        $sth->execute;
        $sth->execute;
-        $sth->fetchrow_array;
+       my $min = $sth->fetchrow_array;
+       $sth = $dbh->prepare_cached('SELECT MAX(num) FROM msgmap', undef, 1);
+       $sth->execute;
+       ($min, $sth->fetchrow_array);
 }
 
 sub mid_prefixes {
 }
 
 sub mid_prefixes {
index 4987f98109b1c9e284bd6052daafbb69099f28db..e5021532096e3ed53ae7cf123d6b554d3ce02285 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 use Test::More;
 use strict;
 use warnings;
 use Test::More;
-use Benchmark qw(:all);
+use Benchmark qw(:all :hireswallclock);
 use PublicInbox::Inbox;
 use File::Temp qw/tempdir/;
 use POSIX qw(dup2);
 use PublicInbox::Inbox;
 use File::Temp qw/tempdir/;
 use POSIX qw(dup2);
@@ -79,8 +79,13 @@ $s = IO::Socket::INET->new(%opts);
 $s->autoflush(1);
 my $buf = $s->getline;
 is($buf, "201 server ready - post via email\r\n", 'got greeting');
 $s->autoflush(1);
 my $buf = $s->getline;
 is($buf, "201 server ready - post via email\r\n", 'got greeting');
-ok($s->print("GROUP $group\r\n"), 'changed group');
-$buf = $s->getline;
+
+my $t = timeit(10, sub {
+       ok($s->print("GROUP $group\r\n"), 'changed group');
+       $buf = $s->getline;
+});
+diag 'GROUP took: ' . timestr($t);
+
 my ($tot, $min, $max) = ($buf =~ /\A211 (\d+) (\d+) (\d+) /);
 ok($tot && $min && $max, 'got GROUP response');
 my $nr = $max - $min;
 my ($tot, $min, $max) = ($buf =~ /\A211 (\d+) (\d+) (\d+) /);
 ok($tot && $min && $max, 'got GROUP response');
 my $nr = $max - $min;
@@ -100,7 +105,7 @@ sub read_until_dot ($) {
        $n;
 }
 
        $n;
 }
 
-my $t = timeit(1, sub {
+$t = timeit(1, sub {
        $s->print("XOVER $spec\r\n");
        $n = read_until_dot($s);
 });
        $s->print("XOVER $spec\r\n");
        $n = read_until_dot($s);
 });