DBIC の初期化速度改善(by Algorithm::C3 0.02)

DBICスキーマをたくさん(20数個かな)定義したモジュールを use しただけの単純なスクリプトに DProf によるプロファイラをかけてみました。

Algorithm::C3 0.01 時代のプロファイリングがこれ。

Total Elapsed Time = 9.335981 Seconds
  User+System Time = 9.315981 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 58.3   5.436  5.436  18829   0.0003 0.0003  Algorithm::C3::_merge
 21.4   1.995  7.823    491   0.0041 0.0159  Class::C3::_calculate_method_dispa
                                             tch_table
 9.95   0.927  0.927    491   0.0019 0.0019  Class::C3::_remove_method_dispatch
                                             _table
 3.83   0.357  0.357    491   0.0007 0.0007  Class::C3::_apply_method_dispatch_
                                             table
 2.61   0.243  0.243  37658   0.0000 0.0000  Class::C3::__ANON__
 1.66   0.155  5.834  18829   0.0000 0.0003  Algorithm::C3::merge
 1.50   0.140  9.288     29   0.0048 0.3203  Class::C3::reinitialize
 0.85   0.079  0.333     88   0.0009 0.0038  DBIx::Class::Componentised::ensure
                                             _class_loaded
 0.42   0.039  0.058     22   0.0018 0.0026  DBIx::Class::ResultSourceProxy::Ta
                                             ble::table
 0.40   0.037  0.964     29   0.0013 0.0333  Class::C3::_remove_method_dispatch
                                             _tables
 0.32   0.030  0.059      6   0.0050 0.0098  DBIx::Class::Componentised::BEGIN
 0.21   0.020  0.030      3   0.0067 0.0100  vars::BEGIN
 0.21   0.020  0.066      5   0.0040 0.0133  DBIx::Class::ResultSource::Table::
                                             BEGIN
 0.21   0.020  0.019      7   0.0028 0.0027  Encode::BEGIN
 0.20   0.019  0.019    223   0.0001 0.0001  UNIVERSAL::isa

Algorithm::C3 0.02 では…

Total Elapsed Time = 5.167620 Seconds
  User+System Time = 5.157620 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 31.5   1.625  3.299    491   0.0033 0.0067  Class::C3::_calculate_method_dispa
                                             tch_table
 28.6   1.478  1.679    491   0.0030 0.0034  Algorithm::C3::merge
 18.5   0.958  0.958    491   0.0020 0.0020  Class::C3::_remove_method_dispatch
                                             _table
 6.75   0.348  0.348    491   0.0007 0.0007  Class::C3::_apply_method_dispatch_
                                             table
 3.90   0.201  0.201   7888   0.0000 0.0000  Class::C3::__ANON__
 2.52   0.130  4.815     29   0.0045 0.1660  Class::C3::reinitialize
 1.14   0.059  0.296     88   0.0007 0.0034  DBIx::Class::Componentised::ensure
                                             _class_loaded
 0.95   0.049  0.095     46   0.0011 0.0021  base::import
 0.91   0.047  1.005     29   0.0016 0.0347  Class::C3::_remove_method_dispatch
                                             _tables
 0.76   0.039  0.039    223   0.0002 0.0002  UNIVERSAL::isa
 0.72   0.037  0.036    171   0.0002 0.0002  DBIx::Class::AccessorGroup::_mk_gr
                                             oup_accessors
 0.58   0.030  0.058      5   0.0060 0.0116  DBIx::Class::ResultSource::Table::
                                             BEGIN
 0.56   0.029  5.258      3   0.0097 1.7525  main::BEGIN
 0.39   0.020  0.049      6   0.0033 0.0081  DBIx::Class::Componentised::BEGIN
 0.35   0.018  0.048     22   0.0008 0.0022  DBIx::Class::ResultSourceProxy::ad
                                             d_columns

テスト機は Pen3 1GHz でちょっと昔な世代なんですが,2倍の高速化となりました。ちゃんとベンチマークをとったわけではないので数値としての信頼性は微妙ですが,Algorithm::C3::merge と Class::C3::__ANON__ が膨大に呼び出されていたところが改善されていることがわかるとおもいます。

アルゴリズムリファクタリングを行ったということで弊害があるかもしれませんが,参考までに。