Problem with C++ wrapper and gpgme

Marcus Brinkmann Marcus.Brinkmann at
Mon May 26 16:54:02 CEST 2003

On Mon, May 26, 2003 at 12:52:10AM -0500, Robert J. Hansen wrote:
> > Why did that surprise you?

> It surprised me both due to speed and ease-of-use issues.  The speed
> issue was surprising because I was expecting that GPGME, being written
> as the canonical way of interacting with GnuPG, would be optimized for
> speed and efficiency.  For small keyrings GPGME beat the handrolled
> solution by small margins, but as keyrings grew larger GPGME fell
> significantly behind.

GPGME has several conflicting goals.  We want to make simple things simple,
but complex things possible.  We also want it to be a generic framework, and
not specific to OpenPGP (GnuPG).  Furthermore, it needs to be written
carefully to be usable in a lot of environments, and as a shared library the
interface must be written in a way to not hinder future development without
hurting backward compatibility.

Thus, it can be expected that if you only have a very specific, limited task
to perform, a hand written solution optimized to that case can always be
faster then the generic solution with GPGME.  GPGME can not do anything
magical: It still has to do everything that you did in your small wrapper,
plus considerably more to fulfill the above requirements.

However, GPGME _will_ take advantage of future developments to boost
performance.  In the future (with GnuPG v2), GPGME will only start the
crypto engine once per context, and perform all operations with the same
process.  This will considerable improve performance, and does not require
any changes to the programs using GPGME.

> Ease-of-use was likewise surprising.  It turned out to be considerably
> easier to interact with GnuPG through a homegrown C++ wrapper that
> ripped the data from a gpg --list-keys --with-colons --fingerprint than
> it was through GPGME.

As you said, ease of use is something that is very personal.  What might be
easy for you is not easy for others.  If someone is not a good programmer,
he might have difficulties with finding out about the above options, and
with parsing and interpreting the data.  However, listing keys is the most
simple operation gpg can perform.  If you start to take into account more
features like encryption, decryption, listing photo ids, reporting back
progress information, and if you try to do that in a GUI application like GTK+
without blocking, and if you want to allow several operations to run in
parallel, you might quickly find out that GPGME is providing a generic
framework that allows you to do all this without becoming much more
difficult.  IE, you start with something that might be a bit more awkward if
you are used to running shell programs manually and extracting the
information in a simple parser, but the concepts you use will still be
useful in a much more complex environment.
> As a for-example, consider the code we write if we want to display every
> valid, nonrevoked UID.  (This isn't a completely fanciful example,
> either: it's based on a real project I'm working on.)

>       name = 
>         gpgme_key_get_string_attr( key, GPGME_ATTR_NAME, NULL, idx );

You might be happier about the new key interface in GPGME 0.4.x, which is
only available in CVS, because it has not yet been released.  It provides
all information of a key in a struct.

> The C++ code is, from where I stand, easier to read, easier to write,
> easier to correctly use (no manual keylist_end(), no gpgme_release(),
> etc.), and has a significant speed improvement for large keyrings.  

You can not blame us for C not having automatic destructors, which make
keylist_end and gpgme_release necessary, of course, while you can hide them
in the destructor in C++.  In fact, I would expect a C++ wrapper to GPGME
look much more like the first example you gave then the second.  Of course a
C++ wrapper for GPGME should make use of C++ language idioms and features
like iterators, as well.

So, language differences aside, that leaves performance.  I am not aware of
any unnecessary step in GPGME that is a big performance draw.  There might
be a suboptimal use of buffer sizes when reading the output from GPG.
In a somewhat later stage of GPGME development we will certainly come to
profiling the code to check if there are any bottlenecks that must be
addressed.  I also removed the key cache in GPGME 0.4.x which might have
contributed to the problem.

So, after doing the necessary profiling and optimization, I doubt that GPGME
will have an intolerable performance hit (ie, more than a small constant

> Just to be clear, I understand people on-list may well disagree with me
> on the easier-tos.  "Easier" is usually a matter of personal opinion.

If you have particular suggestions for improvement (relativ to the GPGME
0.4.x interface in CVS), please let me know.

Thanks for the feedback,

`Rhubarb is no Egyptian god.' GNU    marcus at
Marcus Brinkmann              The Hurd
Marcus.Brinkmann at

More information about the Gnupg-devel mailing list