はじめに
こんにちは、DIGGLEでWebエンジニアをしている fujita です。
気がつけば2024年も残すところあとわずかとなりました。私は2月にDIGGLEに入社し、非常に充実した、あっという間の1年を過ごしました。今年を振り返り、特に思い出に残っている8月のShibuya.rbで行ったLTの発表について記事にしたいと思います。「うまく発表を行うには」とか「Rubyコミュニティとは」といった内容ではなく、発表してみて私がリアルに感じたことを中心とした記事になります。
Shibuya.rbとは
地域ごとのRubyコミュニティ「地域.rb*1」のひとつで、渋谷近郊のRubyistが定期的に集まり、Rubyの周辺技術共有などを通じて交流を深めているコミュニティです。
なぜ発表しようと思ったか
私自身、プログラミング言語の中ではもっともRubyに親しんでおり、Rubyのよさや面白さを感じていましたし、それについて話したり聞いたりすることが好きでした。実際、社内の1on1で、よくチームリーダーの方とRubyやRuby on Rails(以下、Rails)について話していました。ただ、Rubyコミュニティの活動については多少知っていましたし面白そうだなと思っていたのですが、これまではなんとなく参加したことがない状況でした。特に自分自身が発表することに関しては、やってみたいけど聞く人にとって有益な発表ができるだろうか?と漠然と考えていました。
一方、DIGGLEではこれまでも開発で得られた知見を発信していくことや、私たちが日頃お世話になっている技術コミュニティへの還元を行ってきました。例えばRailsに関するものであれば、Rails7.1へのバージョンアップについてブログ記事を公開しています。ぜひ、ご覧ください。
そんな中、チームリーダーの方から「Rubyに関して何か発表してみませんか?」と声をかけていただきました。具体的な発表テーマが思い浮かんでいなかったため尻込みしていたのですが、「とりあえず発表することを決めてしまえば、なんとかなりますよ」と背中を押していただき、LTでの発表に挑戦することを決意しました!
発表準備
テーマ決め
準備段階の初めは、聞いている方にとって有益な発表にしたいという意識が強く、なかなかテーマが決まらなかったのですが、「5分のLTなので、それらしい結論がなくても自分の関心があることを発表して大丈夫ですよ」とアドバイスいただき、素直に自分が興味を持っていたことを発表テーマとしました。
発表を終えて振り返ってみると、このようにテーマを決定してよかったと思いました。 というのも、今回参加するまではなんとなく技術に関する発表を聞いて勉強する場というイメージがあったのですが、実際には発表に対して様々な視点から質問・意見が飛び交ったり情報共有が行われたりしていました。例えば、以下のような光景がありました。
- 発表内容について詳しくなくても、ラフに「XってYってこと?」のような質問
- 発表内容に関連しそうな記事やgemの共有
- 開発でこんな悩みあるよねの共有
そのため、本当に肩肘張らないラフな内容でも楽しく充実した発表になると思います。裏を返せば、自分が聞き手の時に積極的に発言することが重要だなと感じました。
そもそもLTとは何かということが人によって異なるため、私のように躊躇されている方がいるかもしれません。LTについては以下の記事が参考になりました。
発表内容あらすじ
ここで簡単に発表した内容を説明します。以下はRailsに関するものです。
例として User
モデルがあり、大量の user
レコードをid以外のカラムの値順にDBから取得して処理したいとします。
以前の ActiveRecord::Batches#find_each
*2 は id順にレコードを取得するため、このケースでは利用することができませんでした。(Rails8からは cursor
オプションで並び順を指定してバッチ処理を行うことができるようになりました*3が、以降 find_each
に関する記述は以前のものとします)。そこで find_each
を参考に、同様のメソッド find_each_in_order
を自前で用意したのですが、このメソッドを以下のように利用するとメモリ使用量が大きく増加してしまうことがわかりました。
module FindEachInOrder def find_each_in_order(batch_size: 1000, ...) ... end end User.extend(FindEachInOrder).each { |user| ... }
最終的には、以下のようにすると extend
がない場合と比較してメモリ使用量が大きく増加することがわかり、この現象を発表ネタとしました。
(以下のスライドに記載した実験では、おおよそ、extendがない場合のRSSの増加量10752KBが、extendをつけると18816KBにまで増加しました。)
module EmptyModule; end User.extend(EmptyModule).find_each { |user| ... }
スライド作り
先ほど「LTなので、それらしい結論がなくても」といいましたが、もちろん、できれば発表を聞かれる方に少しでも有益な情報を提供できればという気持ちがありました。また、自分自身にとってもRubyについて深く知るいい機会と捉えていたため、Rubyのソースコード*4やRubyの仕組みに関する資料を読みました。(具体的な内容は、以下のスライドをご覧ください。)
特にRubyのソースコードを読むことはC言語を書いたことがなかったため避けていた部分があるのですが、ソースコードを読めばなんとなくでもRubyがやっていることがわかるという経験ができたのが収穫でした。
一方、発表を振り返ると以下の反省点もあります。
スライド序盤の自己紹介がしっくりこない: 自分とRubyの関わりについて簡潔に伝えられればとは思うのですが……自己紹介って難しいですね。
1枚のスライドに内容を詰め込みすぎ: 文字が小さくて見にくくなってしまったり、自分がスライドのどの箇所について話しているかが伝わりづらくなってしまいました。
GitHub に再現用レポジトリを作成
「発表内容にある『extendでメモリ使用量が大きくなる事象』が再現できるコードを公開しておくと親切ですよ」とアドバイスいただき、簡単なものではありますがレポジトリを用意しました。
発表当日
会場へ
今でも覚えているのですが、当日はびっくりするぐらいの土砂降りで、ビショビショになりながらなんとか会場であるピクシブさんのオフィスに到着しました。 時間を勘違いして30分くらい早く到着してしまってどうしようかなと思っていたのですが、ピクシブさんのオフィスの業務後の様子を見たり(興味津々で見ていました)、次々に来られる方々との挨拶をしているとあっという間に時間が経ち、オープニングの時間になりました。 また、チームの同僚が悪天候の中来てくれて、とてもうれしかったです。
発表
発表スペースには大きなスクリーンがあり、発表が見やすい環境をピクシブさんが準備してくださっていたのですが、先ほど挙げたスライドの反省点「1枚のスライドに内容を詰め込みすぎ」に発表中に気づき、あたふたしてしまいました。また発表時間5分に対して内容を詰め込みすぎたため、最後のほうはスライドをいくつかとばすことになりました。 発表のリハーサルの大切さを痛感しました……
発表後
私の発表に関して色々な方が話しかけてくださり、以下のようなことをお話ししました。
- 前述の例でいえば、「そもそも
user
レコードをバッチ処理する際に、特定の順序で処理する必要があるのはなぜか?仕様から並び順の要素を取り除く選択肢は考えたか」というような質問をいただきました。発表ネタの現象はパフォーマンス課題を解決するタスクに取り組む中で発見したものですが、パフォーマンスの改善方法として技術的なものにフォーカスしてしまっていたことに、恥ずかしながらその時気づきました。広い視野をもって課題解決することの重要性に改めて気づくことができました。 - 「Railsの
find_each
は、なぜid順でしかバッチ処理できないのか」ということを話しました。その中で、「orderするカラム(群)に対してレコードが一意になるようにすること*5」や「limit + offset を避ける形で任意のカラムでorderすること」*6に関してハードルがあるのかもしれないねという話が出ました。実はこれらのハードルは発表では触れなかったのですが、実際に私がfind_each_in_order
を実装する際に気にかけていた部分だったため、色々話している中でこの話題にたどり着いたことに驚きとうれしさを感じました。開発の中で出会った課題って、誰かと共有できるとうれしいものですよね!
振り返りと今後の展望
今回参加してみて、技術にとどまらず様々なことを社外の方とお話しでき、非常に楽しかったです。発表する・しないに関わらず、今後もこのような会に参加してみたいと思います。特に、参加する際は発表を聞く側として積極的に発言していきたいなと思いました。
We're hiring!
DIGGLEではともにプロダクトを開発してくれるエンジニアを大募集中です。
少しでも興味があれば、ぜひ下記採用サイトからエントリーください。
カジュアル面談も実施しているので、気軽なお気持ちでご応募いただければと思います!
*1:https://scrapbox.io/ruby-jp/%E5%9C%B0%E5%9F%9F.rb
*2:https://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_each
*3: https://github.com/rails/rails/blob/8-0-stable/activerecord/CHANGELOG.md#rails-800beta1-september-26-2024
*4:https://github.com/ruby/ruby
*5:Rails8以降のfind_eachでは、このあたりでチェックしているようです。
*6:これらの詳細については https://use-the-index-luke.com/sql/partial-results/fetch-next-page にわかりやすく書かれています。気になる方はそちらをご覧ください。