Rose::DB::Object - High Performance Perl ORM
Posted in perl, orm, rdbo Thu, 01 Jun 2006 21:22:00 GMT
In the area of Perl ORM (object relational mappers), there are essentially three players: Class::DBI, DBIx::Class and Rose::DB::Object. Of the three, Rose::DB::Object (a.k.a. RDBO) is known to be the fastest, running just 2-4 times the speed of straight DBI in many tests (albeit using an unloaded database). DBIx::Class is known as the most extensible and flexible. Class::DBI is considered outdated (e.g. it doesn't support JOINs) and to be avoided by many. RDBO is the fastest because speed is it's primary design consideration, implementing many perl and DBI-level optimizations. The design philosophy is described as:
Basically, any work that can be done "up-front" (or at least "infrequently") is done in order to keep the frequently used runtime code path very tight. - John Siracusa
RDBO's implementation accomplishes this feat in several ways:
- aggressive code inlining: method calls can be very expensive and RDBO goes to great lenghts to avoid this. The get_objects method in Rose::DB::Object:Manager is 2129 lines long.
- extensive caching of "derived metadata", e.g. commonly used SQL query strings, column lists, etc.
- extensive use of "the 'fast path' in DBI, such as always using bind_col() and fetch() to retrieve data instead of fetchrow_array(), unbound calls to fetchrow_arrayref(), or fetchrow_hashref()."
- "compiling down" accessor and mutator methods, both with and without triggers, to an optimized form in order to shorten the code path.
Achieving this high performance has resulted in some compromises. They include:
- the code is harder to maintain and extend, resulting in a smaller community of contributors.
- aggregate functions and other queries that do not return table rows (e.g. GROUP BY, HAVING, etc.) are not natively supported yet. A previous entry, Rose::DB::Object - aggregates, describes how to implement aggregates with RDBO.
Perl has a TIMTOWTDI tradition and ORMs are no exception. The primary alternative, DBIx::Class, is designed with extensibility as it's primary consideration and addresses the compromises RDBO has made. The implementation gives up some perl execution speed to RDBO to gain this extensibility while generating roughly equivalent SQL for a similar database load. Both RDBO and DBIC are much faster than Class::DBI. The extensibility philosophy has resulted in an alternative ORM that is more flexible, supports aggregate functions and has a larger community of committers relative to RDBO.
RDBO should be a strong contender if you want the fastest Perl ORM and can accept the design decisions it has made to achieve that performance. If you would like some extra capability and can give up some perl execution speed in your web nodes, it may be worthwhile to evaluate some alternatives.
I don’t think you can extrapolate from the presence of extensive inlining to the smaller number of developers. The number of developers is influenced by many factors, perhaps the least of which is the amount of inlining in some portions of the code.
Also remember that only the “hot” code path is aggressively optimized. All of the “setup” stuff (metadata, database support, column types, relationships, etc.) is designed for extensibility, since it is only done up-front rather than repeatedly.
Finally, performance issues aside, RDBO also has many other unique features. For example, there’s extensive built-in support for many column data types, “smart” column value inlining, “flattened” many-to-many relationships, etc. RDBO also goes a long way towards hiding vendor-specific differences between databases.
DBIC also has many unique features. It’s not just a “more flexible” version of RDBO, nor is RDBO just a “less flexible, but faster” version of DBIC. (Besides, both statements depend on what you mean by “faster” and what, exactly, you want to “flex” :) There are significant differences in the APIs as well.
You can find a longer summary of the differences between DBIC and RDBO here:
http://sourceforge.net/mailarchive/message.php?msg_id=17104748
I clicked the sourceforge.net link and was told I had to login. I registered for access and tried again, but I don’t even have read access.