Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rubyのextendであったこわい話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for MasashiFujita MasashiFujita
August 23, 2024
490

 Rubyのextendであったこわい話

Avatar for MasashiFujita

MasashiFujita

August 23, 2024
Tweet

Transcript

  1. 自己紹介 名前:藤田 将志 所属:DIGGLE株式会社 自己紹介: • Ruby on Rails や

    React などを使用した、管理会計のためのtoBのSaasを開発し ています。 ◦ 弊社は2023、2024Ruby会議のスポンサーで、とても Rubyにお世話になっています 😊 • 兵庫県神戸市出身で、とても関西が恋しいです
  2. heap-profiler 実行結果を細かく見ると extendあり Total allocated: 172.37 MB (1342040 objects) Total

    retained: 9.11 MB (34481 objects) allocated objects by file ----------------------------------- 6637 activerecord-7.1.3.4/lib/active_record/relation/query_methods.rb 4148 activerecord-7.1.3.4/lib/active_record/relation.rb 2001 activerecord-7.1.3.4/lib/active_record/relation/batches.rb 815 <internal:kernel> 578 activerecord-7.1.3.4/lib/active_record/relation/delegation.rb extendなし Total allocated: 171.48 MB (1334457 objects) Total retained: 9.10 MB (34108 objects) allocated objects by file ----------------------------------- 2988 activerecord-7.1.3.4/lib/active_record/relation/query_methods.rb 1230 activerecord-7.1.3.4/lib/active_record/relation.rb 1701 activerecord-7.1.3.4/lib/active_record/relation/batches.rb なし <internal:kernel> 476 activerecord-7.1.3.4/lib/active_record/relation/delegation.rb
  3. なんとなくわかったこと1 allocated memory by location ----------------------------------- 645.08 kB <internal:kernel>:48 extendありのケースでは、<internal:kernel>:48

    の実行によっ て、オブジェクトが生成されている ruby/kernel.rb ActiveRecord::QueryMethods#where ActiveRecord::Batches#find_each 内では、relation.whereによって、 User::ActiveRecord_Relation オブジェクトのcloneが発生する → clone 生成物ごとに異なる singleton_class が生成される → 多くのオブジェクトが作成される ActiveRecord::SpawnMethods#spawn
  4. なんとなくわかったこと2 extendありのケースでは、 callcache がより多く生成される。 callcache: インラインメソッドキャッシュ のためのオブジェクト allocated objects by

    class ----------------------------------- 11652 <callcache> (IMEMO) ・・・extendあり 4275 <callcache> (IMEMO) ・・・extendなし インラインメソッドキャッシュ : 笹田 耕一『プログラム言語 Ruby におけるメソッド キャッシング手法の検討』 より引用 メソッドディスパッチ命令 send のオペランドにメ ソッ ドキャッシュ用のオペランドを用意し,その領域に レ シーバのクラスとメソッド定義情報を格納する.ディス パッチ時,レシーバのクラスをキャッシュしたクラス と 比較し,等しければヒットとする. rb_callcache
  5. なんとなくわかったこと2 WEB+DB PRESS Vol.122 笹田 耕一「Rubyのウラガワ」 P.143より引用 注16 クラスが異なるとメソッド探索が失敗します。つまり、同 じクラスのオブジェクト

    でも、それぞれが特異クラスを 持っているとクラスが異なると判定され、キャッ シュが効 きません。性能が必要な場面では特異クラスを作らないよ うにする とよいかもしれません。
  6. なんとなくわかったこと2(補足) 【参考】その他、extendによるメモリ使用量への悪影響 • Call Cache for singleton methods can lead

    to "memory leaks" ◦ 引用:Eregon (Benoit Daloze) さんのコメント As a general note, creating a singleton class is not cheap, this should only be used for class objects (which always have one) and for a few rare global objects where it's convenient. Using Object#extend objects often/on the fast path is just "making programs slow and uncached". (訳)一般的な注意点として、シングルトンクラスの作成はコストが高いので、常にシングルトンクラスを持つクラ スオブジェクトや、便宜上必要な少数のグローバルオブジェクトにのみ使用すべきです。 `Object#extend` を頻 繁に使用したり、高速パスで使用したりすることは、単に「プログラムを遅くし、キャッシュを効かなくする」ことに なります。 • PoC: Cache Extended Collection Proxies