Clas::DBIをプロファイリング

| コメント(0) | トラックバック(0)




http://d.hatena.ne.jp/nekokak/20060127/1138335790



Class::DBI v3.0.14で上記URLにあったシンプルなRetrieveをDevel::DProfでプロファイリングしてみた。



/usr/local/bin/perl
  -MNikkiSite::Data::Loader -d:DProf -e '
      for(1..10000) {
         my $it = NikkiSite::Data::Users->search({ uid => "daisuke" });
         while (my $rec = $it->next) { print $rec->uid, "\n"}
      }'

最初、1..100くらいでやってみたのだけど、これがロードタイムのほうが遥かに大きくて、base::importとかBEGINブロックとか、そういうのばっかりがカウントされるので、10000回まで大きくしてみた。

で、これをdprofppでみてみる:

daisuke$ dprofpp -f 'YAML|Params::Validate|DateTime|NikkiSite' -O 20
<snip>
Total Elapsed Time = 18.86988 Seconds
  User+System Time = 7.494887 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 8.47   0.635  0.635 162584   0.0000 0.0000  Class::Accessor::Fast::__ANON__
 5.42   0.406  0.996  10000   0.0000 0.0001  Class::DBI::SQL::Transformer::_do_
                                             transformation
 4.95   0.371  2.363  10000   0.0000 0.0002  Class::DBI::sth_to_objects
 4.92   0.369  0.376 100802   0.0000 0.0000  Class::Data::Inheritable::__ANON__
 4.58   0.343  0.839  10185   0.0000 0.0001  DBIx::ContextualFetch::st::_untain
                                             t_execute
 4.54   0.340  1.699  10000   0.0000 0.0002  Class::DBI::transform_sql
 4.31   0.323  0.323  10186   0.0000 0.0000  DBI::st::execute
 4.06   0.304  0.789 130776   0.0000 0.0000  Class::DBI::Column::name_lc
 4.00   0.300  0.300  10106   0.0000 0.0000  DBD::Pg::db::_ping
 3.63   0.272  1.064 130096   0.0000 0.0000  Class::DBI::Column::__ANON__
 3.31   0.248  0.248  71077   0.0000 0.0000  DBI::common::FETCH
 3.23   0.242  0.241  20010   0.0000 0.0000  Class::DBI::_require_class
 3.03   0.227  0.328  20000   0.0000 0.0000  DBIx::ContextualFetch::st::fetch
 2.98   0.223  1.382  20000   0.0000 0.0001  Class::DBI::Iterator::next
 2.92   0.219  0.785  10000   0.0000 0.0001  Class::DBI::Search::Basic::_search
                                             _for
 2.82   0.211  1.039  20000   0.0000 0.0001  Class::DBI::Search::Basic::_qual_b
                                             ind
 2.39   0.179  0.179  40142   0.0000 0.0000  Class::DBI::ColumnGrouper::group_c
                                             ols
 2.19   0.164  0.277  10000   0.0000 0.0000  Class::DBI::_fresh_init
 2.13   0.160  0.254  10000   0.0000 0.0000  DBD::_::db::prepare_cached
 2.13   0.160  0.340  10000   0.0000 0.0000  Class::DBI::_my_iterator

ふーん、結構色々やってるなぁ。name_lc()とかはキャッシュするだけでカットできる(Class::DBI::Column::__ANON__も同じname_lcを使ってるからその分だけはやくできる)。あとのはもう、コールスタックを減らすくらいしか最適化の場所がないような・・・

というわけで、時間もないので一番簡単にわかるところで2行ハックして再度プロファイリング。

  # Class/DBI/Column.pm
  use strict;
  use base 'Class::Accessor::Fast';
  use Carp;

__PACKAGE__->mk_accessors(
qw/name name_lc accessor mutator placeholder is_constrained/
);

<snip>

sub new {
my $class = shift;
my $name = shift or croak "Column needs a name";
my $opt = shift || {};
return $class->SUPER::new(
{
name => $name
name_lc => lc $name,
accessor => $name,
mutator => $name,
_groups => {},
placeholder => '?',
%$opt,
}
);
}


さー、これで10000回走らせてプロファイリング



daisuke$ dprofpp -f 'YAML|Params::Validate|DateTime|NikkiSite' -O 20
Total Elapsed Time = 16.16692 Seconds
User+System Time = 7.034115 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c Name
8.15 0.573 0.573 162584 0.0000 0.0000 Class::Accessor::Fast::__ANON__
6.38 0.449 2.011 10000 0.0000 0.0002 Class::DBI::sth_to_objects
5.60 0.394 0.394 10186 0.0000 0.0000 DBI::st::execute
5.13 0.361 0.368 100802 0.0000 0.0000 Class::Data::Inheritable::__ANON__
4.49 0.316 0.316 10106 0.0000 0.0000 DBD::Pg::db::_ping
3.67 0.258 0.887 10000 0.0000 0.0001 Class::DBI::SQL::Transformer::_do_
transformation
3.67 0.258 0.383 20006 0.0000 0.0000 Class::DBI::ColumnGrouper::find_co
lumn
3.54 0.249 0.777 10185 0.0000 0.0001 DBIx::ContextualFetch::st::_untain
t_execute
3.43 0.241 0.651 130096 0.0000 0.0000 Class::DBI::Column::__ANON__
3.11 0.219 0.226 20010 0.0000 0.0000 Class::DBI::_require_class
3.06 0.215 1.535 10000 0.0000 0.0002 Class::DBI::transform_sql
2.94 0.207 0.566 10000 0.0000 0.0001 Class::DBI::_live_object_key
2.83 0.199 1.421 20000 0.0000 0.0001 Class::DBI::Iterator::next
2.66 0.187 0.953 20000 0.0000 0.0000 Class::DBI::Search::Basic::_qual_b
ind
2.66 0.187 0.316 10000 0.0000 0.0000 Class::DBI::_fresh_init
2.66 0.187 0.308 30064 0.0000 0.0000 Class::DBI::ColumnGrouper::primary
2.45 0.172 0.738 10000 0.0000 0.0001 Class::DBI::Search::Basic::_search
_for
2.32 0.163 0.163 40142 0.0000 0.0000 Class::DBI::ColumnGrouper::group_c
ols
2.00 0.141 0.230 10000 0.0000 0.0000 Class::DBI::Search::Basic::new
2.00 0.141 0.285 30000 0.0000 0.0000 Class::DBI::_attrs

ほい、name_lcは消えた。2行で10%違ったらたいしたもんだと思います。ふーん、なんかまだ色々できそうな予感。怪しいものとしてはColumnGrouperかな。


Author

Daisuke Maki (a.k.a lestrrat): Perl hacker, Director of Japan Perl Association, YAPC::Asia Tokyo Organizer (2009-2012), Fluent in Japanese, English. Ex-Brazilian (sorta)

#perl #c #ruby #java #mysql #english #japanese #opensource #stf #cooking #scotch #cigar


このエントリーをはてなブックマ
ークに追加

翔泳社よりモダンPerl入門(2010)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ