@ledsun blog

無味の味は佳境に入らざればすなわち知れず

GCの影響は少なそう

AWS EC2上で並列処理の時間を再々計測した - @ledsun blog で、次の3つの仮説を立てました。

  1. コピーがボトルネックではなかった
  2. コピーは減ったが相変わらずボトルネックである
  3. コピーで作られたオブジェクトのGCボトルネックだった

また1は可能性が低いと判断しました。 今回は3の可能性を検証します。

対象の処理は全体はActiveJobで実装しています。 そこで次のようなコールバックを定義して、GCの実行回数をしらべます。

  around_perform do |job, block|
    GC.start
    GC.stat => {minor_gc_count: prev_minor_gc_count, major_gc_count: prev_major_gc_count}
    block.call
  ensure
    GC.stat => {minor_gc_count: minor_gc_count, major_gc_count: major_gc_count}
    tengu_p minor_gc_count - prev_minor_gc_count, major_gc_count - prev_major_gc_count
  end

右代入というやつを初めて使いました。 余談です。

計測した結果は次の通りです。 249文章を処理しおわった時にジョブを中止して、その間に発生したGCの数を数えました。

minor_gc_count major_gc_count
Ractorなし 264 12
コピー2回 227 14
コピー1回 308 17

コピー回数とGCの回数には相関がありません。 「コピーで作られたオブジェクトのGCボトルネックだった」の可能性も低そうです。

消去法で「コピーは減ったが相変わらずボトルネックである」の可能性が高くなりました。 ここに注力するのが良さそうです。

参考