ar_fixturesが遅い
ユニットテストがしたくなったのでとりあえずar_fixturesとyaml_wamlをインストールして動かしてみて10分ほど放置。だがまったく終わらない。
インタラプトしてカウンタを仕込んで目検してみるに、どうも秒間5〜6件程度しか処理できていない気がする。
対象テーブルのテストデータは2万件…そりゃ終わるわけないだろ。。。常識的に考えて。。。
とりあえずの対処法
そもそもテストデータ二万件もいらねーだろ、って事でまず第一の対処法は、作成するテストデータの数を制限する事。
ruby script/runner "Model.to_fixture(5)"
こんな感じにto_fixtureメソッドに引数を付けると件数を制限することができる。
でもなんか気になるので
どこの処理が重たいのかを調べるためにプロファイラ初体験。
>ruby -r profile script/runner "Model.to_fixture(500)" % cumulative self self total time seconds seconds calls ms/call ms/call name 5.98 7.10 7.10 475 14.94 27.76 String#gsub 5.96 14.18 7.08 11014 0.64 11.87 Proc#call 5.90 21.18 7.01 8500 0.82 1.35 String#taguri 4.89 26.98 5.80 11001 0.53 12.58 YAML.quick_emit 2.84 30.35 3.36 2460 1.37 29.03 Array#each 2.64 33.47 3.13 5184 0.60 1.15 Mysql#get_length 2.38 36.30 2.82 10500 0.27 0.45 YAML::Syck::Scalar#initialize 2.21 38.92 2.62 646 4.06 340.34 Kernel.gem_original_require 2.15 41.46 2.55 8500 0.30 4.44 String#to_yaml_without_decode 2.14 44.00 2.54 17500 0.14 0.24 Object#to_yaml_properties 2.01 46.39 2.39 35465 0.07 0.08 Array#pack 1.89 48.63 2.24 25246 0.09 0.11 Kernel.=== 1.86 50.83 2.20 8500 0.26 4.77 String#to_yaml 1.85 53.02 2.19 8500 0.26 0.58 String#is_complex_yaml? 1.74 55.09 2.06 5011 0.41 1.08 ActiveRecord::ConnectionAdapters::Column#type_cast 1.62 57.01 1.92 6115 0.31 0.41 Object#method_added 1.60 58.91 1.90 5001 0.38 2.60 ActiveRecord::Base#read_attribute 1.60 60.80 1.89 27566 0.07 0.07 Kernel.class 1.58 62.68 1.88 11001 0.17 12.04 YAML::Syck::Emitter#emit
トップのgsubメソッドはyaml_wamlプラグインでやってるマルチバイト対応処理っぽい。
yaml_wamlではすべてのクラスのto_yamlメソッドを置き換えていて、オリジナルのto_yamlメソッドはAliasでto_yaml_without_decodeメソッドに置き換えられている。
とりあえずyaml_wamlプラグインをはずして再度プロファイル。
% cumulative self self total time seconds seconds calls ms/call ms/call name 6.46 6.67 6.67 11014 0.61 12.32 Proc#call 6.09 12.95 6.29 8263 0.76 1.16 String#taguri 4.77 17.88 4.93 11001 0.45 12.88 YAML.quick_emit 4.06 22.07 4.19 8500 0.49 0.86 String#is_binary_data? 3.66 25.84 3.77 17263 0.22 0.31 Object#to_yaml_properties 3.31 29.25 3.41 2456 1.39 28.61 Array#each 3.07 32.42 3.16 5184 0.61 1.20 Mysql#get_length 2.52 35.01 2.60 5001 0.52 2.70 ActiveRecord::Base#read_attribute 2.44 37.53 2.51 644 3.90 311.50 Kernel.gem_original_require 2.16 39.76 2.23 8500 0.26 5.06 String#to_yaml 2.13 41.96 2.20 10500 0.21 0.43 YAML::Syck::Scalar#initialize 2.06 44.08 2.12 5011 0.42 1.02 ActiveRecord::ConnectionAdapters::Column#type_cast
予想通りString#gsubはなくなったものの、突出して処理時間を食っているメソッドがあるわけではないようだ。
でも肝心のto_yamlメソッドの処理時間は全体のたった2%。うーむ…。
呼び出し元クラスが分かればまた違った結果が見えてくるのかもしれないが…。
スキル不足のようなのでレベルが上がったら再チャレンジしたいところ。