[Dbix-class] (no subject)

Eden Cardim edencardim at gmail.com
Mon Jul 2 13:07:13 GMT 2012


>>>>> "Dami" == Dami Laurent (PJ) <laurent.dami at justice.ge.ch> writes:

    Dami> Hi DBIC list,
    Dami> For info, I gave a talk at the French Perl Workshop 2012
    Dami> about comparing DBIx::Class (DBIC) and DBIx::DataModel (DBIDM);
    Dami> at this occasion I did a few benchmarks that may be worth sharing
    Dami> with you :

    Dami> Extract & print 2 columns from a single table (109349 rows)
    Dami>   - raw DBI                    0.43 secs
    Dami>   - DBIC regular              11.09 secs
    Dami>   - DBIC hashref inflator     10.06 secs    
    Dami>   - DBIC 'raw data' (cursor)   4.48 secs
    Dami>   - DBIDM regular              4.00 secs
    Dami>   - DBIDM fast statement       2.25 secs

    Dami> Join 3 tables & print 4 columns from the join (113895 rows)
    Dami>   - raw DBI                                     1.36 secs
    Dami>   - DBIC regular                               46.70 secs
    Dami>   - DBIC, join & +columns                      15.50 secs
    Dami>   - DBIC, join & +columns, hashref inflator    14.17 secs
    Dami>   - DBIC, join & +columns, 'raw data' (cursor)  6.59 secs
    Dami>   - DBIC, prefetch                            146.29 secs
    Dami>   - DBIDM regular                               5.01 secs
    Dami>   - DBIDM fast statement                        3.28 secs

    Dami> I was not surprised to find out that DBIC is slower
    Dami> than DBIDM :-) ; however, I was quite surprised to 
    Dami> find out that, among DBIC mechanisms :

DBICDM is a bit faster yes, but it's also less flexible and robust, it's
a well-known trade-off. You're comparing an F1 car with a Jeep on a
paved highway. :)

    Dami> a) 'HashRefInflator', often advocated as being the fast way to get
    Dami>    data from DBIC, actually doesn't seem to bring any significant
    Dami>    benefit.

Indeed, for the use case you're benchmarking, there is no purpose or
advantage to using DBIC because you're just printing out the values in
the same tabular format you're obtaining from the database. The extra
work goes into collapsing the cartesian products into an actual data
structure. Assuming you don't need this structure, there is no case for
using DBIC or any other ORM. You should try the same benchmarks and
print out a tree-like structure.

    Dami> b) 'prefetch', also advocated for doing speed improvements, indeed 
    Dami>    does its job of sparing queries to the database, but then has  
    Dami>    such a high cost in handling the retrieved data that it becomes
    Dami>    the most expensive method.

The way you're querying and displaying the results is what's responsible
for the cost of that benchmark, given you're building N^3 objects
throughout the entire run, and you're invoking a method for displaying
the columns. You should get a speed improvement by using
$row->get_columns instead.

    Dami> c) 'cursor', which goes directly to the DBI layer and therefore
    Dami>    loses all ORM features for the retrieved data, nevertheless 
    Dami>    adds a significant cost over raw DBI.

Of course it adds cost, if you're using something like DBIC, it's
because you need structure in your fetched data, if you use raw DBI,
you're just delaying the building of a data structure with the fetched
data. Of course, this is useful for dodging a benchmark. But in a real
application, when you start passing that data around throughout the
various layers, you're gonna need the structure and you'll be penalized
anyway. DBIC is designed to be a fast kick-start for developing an
application and then optimizing the bottlenecks, for this case, you can
add your raw DBI code in a custom cursor if you need the speed.

    Dami> Since I'm not an expert of DBIC, I may well have done something wrong
    Dami> in those benchmarks; so please correct me if necessary.
    Dami> The source code is at https://github.com/damil/compare-ORM

    Dami> The FPW12 talk also discussed various design aspects; the slides are at
    Dami> http://www.slideshare.net/ldami/dbixclass-vs-dbixdatamodel.

It might be worth mentioning that slide 14 has a few
erroneous/incomplete statements regarding DBIC schema declaration:

- one file for each class -- there is currently no constraint besides
  the perl language syntax/semantics on the amount of files per class,
  you can declare your result classes in a single file if you with to do
  so.

- regular perl classes -- DBIC supports dynamic class creation and is
  even capable of introspecting your database schema and deriving all
  relationships from it automatically (except many to many, for obvious
  reasons) without any manual intervention besides the configuration of
  the connection with the database, this compensates for the two-way
  relationship declarations in most scenarios. The dynamic generation
  approach is generally not recommended because it adds several
  maintainance complexities which make it inviable for use in industrial
  scale applications (which generally evolve spontaneously from "simple"
  applications). It might be worth mentioning that DBIC also supports a
  "hybrid" approach, where you generate the classes dynamically and then
  add static modifications to it.

- full column info -- DBIC also supports plain column-name-only
  declaration.

-- 
      Eden Cardim         Need help with your Catalyst or DBIx::Class project?
      Code Monkey                 http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.    Want a managed development or deployment platform?
 http://edencardim.com            http://www.shadowcat.co.uk/servers/



More information about the DBIx-Class mailing list