Tuesday, April 28, 2009

Making GMime Even More Awesome

I've started working on GMime 2.6, which unfortunately will need to break API with 2.4 in order to achieve the next level of awesome.

If you use GMime (or are thinking of using it) in your project and have some suggestions on how GMime can improve, don't hesitate to fire an email off to gmime-devel-list@lists.gnome.org (preferably after subscribing to the mailing-list first).

These are my current plans:

  • Replace all uses of g_signals with my own event stuff. None of this needs to be public and my events are a lot more performant. [ DONE ]
  • Need to add a Changed event to GMimeHeaderList so that GMimeMessage can listen to changes in the toplevel mime_part's headers. When they change, we need to unset the cached header stream on the GMimeMessage. (see the "Note:" comments in message_write_to_stream and message_get_headers, while this hack works, it'd be nicer if we did it based on event callbacks)
  • Get rid of GMimeSession and replace it with GMimePassphraseRequestFunc or something. See GpgMe's passphrase request callback signature for ideas. [ DONE ]
  • Consider optionally using GpgMe so that we can support S/MIME?
  • Consider GCancellable and GError for GMimeStreams and GMimeParser
  • Add GIO-based GMimeStream and bump glib dep to 2.16 [ DONE ]
  • Add a g_mime_part_get_best_content_encoding()? [ DONE ]
  • Rename GMimeBestEncoding enum to GMimeEncodingConstraint? This might be a better name for the enum to reflect what it's actually meant for. Maybe also move it from gmime-filter-best.h to gmime-encodings.h?
  • How about a g_mime_part_get_best_charset()? This one could be awkward since it depends on the content being UTF-8 text
  • Should either rename g_mime_filter_best_encoding() to get_encoding() or else make sure that GMime.metadata 'fixes' the method name to be GetEncoding so that it will appear as a C# property getter.

2 comments:

Sankar said...

>>>> Replace all uses of g_signals with my own event stuff. None of this needs to be public and my events are a lot more performant.

I dont want to complain about this. but in evo we had(ve) these issues of elist -> gslist, etree -> gtktreeview, camelobject -> gobject etc. popping up when the g* performance has improved.

So, imho, it may be good to stick to the standard g* than writing our own gmime* , for making it easy to maintain in long term. and you'll get other benefits like free-porting, free language binding etc. Do I sound foolish ;) ?

Jeffrey Stedfast said...

Hey Sankar! A few things:

CamelObject was never really done out of performance needs, it was done because at the time GObject didn't exist, only GtkObject did. The main issue at the time was thread-safety.

But back to my GMimeEvent stuff, those APIs are all internal (for now?) and don't want them exposed to the public. They are simply used for keeping relational objects in sync with each other.

Back when I was working on 2.4, I noticed a huge amount of time was spent in the g_signal code even though most of that time the signals were being blocked, so I dropped in a simple event system just to see if that solved it and suddenly parsing an mbox was 20% faster. There's also some performance to gain from moving away from GObject (roughly another 5-10% iirc), but I'm sticking with GObject for now since it is more consistent with the rest of the GNOME APIs.

I tried digging into the GObject performance problems but was never able to figure them out.

As far as the g_signal stuff, I think part of the problem was that blocking and unblocking signals in glib is very costly. I should probably look into this again, though, so maybe I can provide some useful numbers to the glib devs.

Code Snippet Licensing

All code posted to this blog is licensed under the MIT/X11 license unless otherwise stated in the post itself.