Making the OrientDB ODM 5 times faster

Today, after heavily testing performances on a project, I pushed some small but precious changes to the orientdb-odm.


Premature optimization is the root of all evil

In these days I was testing performances of a service I am building with OrientDB and the doctrine ODM that we built so far.

Following one of the golden rules for software architects, we didn’t paid attention to performances – at first – but rather went for a design which would allow us to inject behaviours and easily change portions of code (also thanks to the test suite), I knew that I would have noticed huge flaws at performance level when testing it with production data.

A few days ago we committed fetchplans for repository classes, but it wasnt enough: rather then concentrating on which data we should fetch, I realized one major improvement could be applied on how we map data.

The golden rule

When you write a OXM (object-something mapper) you will shortly understand that a huge portion of your job consist into abstract your design, to ease integration of multiple components into your application: repositories, the object manager, POXO, the data mapper, proxy classes and so on.

Of course, abstraction comes with a cost: slow performances, so one of the first things that you do is starting to cache everything.

How we did it

With a single commit – there’s always room for improvements – the ODM is now able to hydrate objects 5 times faster: when you hydrate similar objects from OrientDB (for example, 2 records that share the same attributes’ values, like is_published or country), there is no need to duplicate operations, so we added a cached inflector (with an in-memory / single request cache) and did some other improvements to the Mapper:

There is no rocket science in what we did, but benchmarks ensure that it’s a huge performance improvement.

By the way, we used Webgrind

Doing almost all of my work from a Mac, I kind of missed KCacheGrind for profiling, so I was looking for an alternative (no, installing XHPROF isn’t an alternative at 2 in the morning) and I found Webgrind (which is cross-platform), a web profiler that requires zero setup: you basically just need to provide it access from the webserver and, by opening it with a browser, the application automatically launches and parses the cachegrind files generated by XDebug.

Webgrind’s code is a bit of a mess, but then, the result is still pretty good – you get a good overview of the expensiveness of your calls as well as a call graph compiled in DOT, which is a de-facto standard for graph generation.

In the mood for some more reading?

...or check the archives.