DBus Performance

Ah, the classic DBus performance issue has reared it's head on Planet Gnome again. I'll chip in my thoughts on this, as I've done a fair bit of profiling on a large user of DBus.

When I first ported of EDS to DBus, it didn't perform as fast as the original ORBit implementation. However when I dug out OProfile I discovered that the main bottle necks were deep in EDS itself, and DBus although in the profiles, wasn't anywhere near the top. We spent a few months optimising EDS-DBus (there was some serious low-hanging fruit) and by the time we'd done the obvious optimisations, EDS-DBus was faster than upstream EDS for the typical usage (running a book view, which happens every time you search in Evolution).

For some methods EDS-DBus was still slower than EDS, and getContacts() is a perfect example. This method takes a query, builds the set of contacts that match, and sends it back to the client in a single list (compared to book views that do the same thing incrementally, and provide future updates). When profiled you discover that libdbus and libc are the top offenders, taking almost 70% of the runtime. The benchmark was asking for all contacts, so EDS-DBus was sending a 150 contacts as vCards over the bus in a single list, which amounts to about 100Kb of data. Now, this gets copied when it enters the library, copied again as it enters the sockets to the bus, which then sends it into another socket to the client, which then makes a copy. These copies really hurt, and are one of the things that ORBit does better than DBus: it copies less frequently and has generally had more optimisation time. There are several ways of making it better.

In conclusion, the DBus vs ORBit performance issue isn't a real one generally. It's a rare case where the cost of the transport is the bottleneck (generally only in fake benchmarks), and when the transport is the bottleneck, there are generally other ways of optimising the code: as Havoc says DBus makes doing true asynchronous method calls trivial, and if you are sending huge amounts of data down the bus a private connection should be used (which will also make you a nicer citizen on the bus, as sending huge messages will clog up the tubes).

NP: Kind Of Blue, Miles Davis

12:20 Saturday, 22 Jul 2006 [#] [computers] (3 comments)

Posted by John (J5) Palmieri at Sat Jul 22 13:40:22 2006:
Ross,

It's D-Bus - http://www.j5live.com/?p=234 ;)
Posted by RichB at Sat Jul 22 16:42:45 2006:
Random thought: If DBus is the great server to client transport with a defined protocol, is the Internet server to client analogy Google's gData?

Oh, nevermind.
Posted by Havoc at Sat Jul 22 19:25:39 2006:
I think the raw libdbus number of copies has only one remaining place for improvement, right now you should see this:
- app copies into DBusMessage
- libdbus copies DBusMessage to the socket
- bus daemon copies from socket to a DBusMessage
- then from DBusMessage into another socket
- other app copies from socket to DBusMessage

The only theoretically removable copy here while still using sockets is "app copies into DBusMessage" - that mailing list post I linked from my blog mentions what the API could be like, but it's probably not worth the pain.

The GLib bindings obviously add more copying, perhaps more than needed, I'm not sure.

Also obviously using the bus daemon inherently gives us 2x the number of copies.

One simple thing to try, if transferring data with sizes like 100K, might be to use a larger buffer for read()/write() calls. Just a wild thing to try though, might be pointless.

Name:


E-mail:


URL:


Add 8 and 1 (required):


Comment: