Proposal: New keydb format
Neal H. Walfield
neal at walfield.org
Thu Oct 29 11:52:46 CET 2015
Hi,
Some people have complained that GnuPG is slow when accessing the key
db (e.g., [1]). To mitigate this, GnuPG has some ugly caches (commit
492792), which are not completely transparent and introduce subtle
bugs that are very hard to find (see, e.g., commits 60bc518 and
ee7ec12, which demonstrate a cache inconsistency).
Werner was the opinion that the performance problem is due to
signature verification and not due to DB accesses. To test this
theory, I did some measurements yesterday and I implemented a small
prototype, which uses SQLite as the underlying storage engine. It can
be retrieved from git on the neal/next branch.
[1] https://bugs.gnupg.org/gnupg/issue2019
Here are some timing results. I use the Debian keyring
(/usr/share/keyrings/debian-keyring.gpg), which contains 751 keys.
Importing the keyring: 2 minutes (keybox) vs. 8 seconds (new):
$ rm pubring.kdx; time gpg2 --no-default-keyring --primary-keyring
gnupg-kbx:pubring.kdx --import debian-keyring.gpg >/dev/null
gpg: Total number processed: 751
gpg: imported: 751
gpg: public key of ultimately trusted key 2183839A not found
gpg: public key of ultimately trusted key BC15C85A not found
gpg: public key of ultimately trusted key EE37CF96 not found
real 1m52.560s
user 0m6.268s
sys 0m31.604s
$ rm pubring.kdb; time gpg2 --no-default-keyring --primary-keyring
gnupg-kdb:pubring.kdb --import debian-keyring.gpg >/dev/null
gpg: Total number processed: 751
gpg: imported: 751
real 0m7.729s
user 0m5.404s
sys 0m0.332s
Running --check-trustdb: 1 second (keybox) vs 0.2 seconds (new):
$ time gpg2 --no-default-keyring --primary-keyring gnupg-kbx:pubring.kbx --check-trustdb
real 0m0.975s
user 0m0.012s
sys 0m0.032s
$ time gpg2 --no-default-keyring --primary-keyring gnupg-kdb:pubring.kdb --check-trustdb
real 0m0.158s
user 0m0.004s
sys 0m0.004s
Doing a sequential scan is a bit slower with the new format: 1.2s
(keybox) vs 2.5s (new):
$ time gpg2 --no-default-keyring --primary-keyring gnupg-kbx:pubring.kdx -k |
grep ^pub | wc -l
gpg: NOTE: THIS IS A DEVELOPMENT VERSION!
gpg: It is only intended for test purposes and should NOT be
gpg: used in a production environment or with production keys!
751
real 0m1.245s
user 0m1.168s
sys 0m0.076s
$ time gpg2 --no-default-keyring --primary-keyring gnupg-kdb:pubring.kdb -k |
grep ^pub | wc -l
751
real 0m2.515s
user 0m2.432s
sys 0m0.088s
This is likely due to the impedance mismatch between the current
interface for doing a full scan and SQLite API's interface for doing a
full scan (we need to resume the search; currently I reexecute a query
for each new result and skip the previous results). If we decide to
use the new format, it shouldn't be hard to improve this.
I'd be interested in any feedback as well as some more measurements of
the performance in real conditions. Note: the code is incomplete, but
the essentials should work.
Thanks,
:) Neal
More information about the Gnupg-devel
mailing list