Techouse Developers Blog

テックハウス開発者ブログ|マルチプロダクト型スタートアップ|エンジニアによる技術情報を発信|SaaS、求人プラットフォーム、DX推進

RubyKaigi 2024 - Strings! Interpolation, Optimisation & Bugs (Day1)

ogp

こんにちは、2024年に新卒で入社し、ジョブハウスでバックエンドエンジニアをしているププです。

本記事では、1日目のMatt Valentine-Houseさん(@eightbitraptor)によるセッション、Stringの割り当てに関するバグと解決の話について紹介させていただきます。

Strings! Interpolation, Optimisation & Bugs

まず、Stringのメモリ割り当ての説明ですが、Stringは文字列の長さによって割り当てが違うということを知ってますか?

40bytesのヒープ領域に保存されてるものですが、実は16bytesはmetadataとポインタの情報が格納されており、残りの24bytesにStringの内容が入れられています。

それ以上の大きさのStringの場合は、そのサイズに応じて、80、120、320bytesでヒープ領域に格納されます。

Stringのヒープ領域は長さによって分ける

したがって、Stringをconcatする際はその新しいStringのヒープ領域を調整する必要があります。

例えば40bytesのStringと80bytesのStringの場合、80または160bytesにする必要があります。

しかし、ここにはバグが潜んでおり、"slot_size"が正確に計算されない事がわかっています。

それに加えてembeddingしないことから、パフォーマンスにも悪い影響を与えていました。

concatする時はバケットも違って、embeddingもないというバグ

Mattさんはこのバグを解決するために、concatのコードを見て調査しました。

すると、MIN_PRE_ALLOC_SIZEという定数を発見し、その値が48になっていることがわかりました。
「このマジックナンバーは何のためだろう?なぜ48なのだろう?」と思いました。

concatの内容

この流れで元のコミットのコメントを確認してみたら、理由がわかりました。

その時代のパソコンの性能がボトルネックとなり、必要な処理であったようです。

concatのコミットメッセージ

現代の実行環境では必要のない処理であることがわかったので、8行のコードを消してみて実験しました。

すると、パフォーマンスも2倍に上がりました。

8行のコードを消すだけでパフォーマンス2倍まで上がった

こちらのセッションの内容は、London Ruby User Groupでも発表されておりますので、是非以下の動画もご参照ください!

https://assets.lrug.org/videos/2023/february/matt-valentine-house-strings-interpolation-optimisation-and-bugs-lrug-feb-2023.mp4assets.lrug.org

感想

技術的にも非常に面白いセッションでしたが、開発への取り組み方に関しても、参考になる箇所がありました。

  1. 自分の理解のためにも、想像で補わず、コードを読んで実装を追うべきだ。
  2. 自分のためでなく、将来の人のために、コミットメッセージはしっかりと書いた方がいい。

私も今まで書いたコミットメッセージは良くないものが多いため、この話を聞いた今からはしっかりと書こうと思いました。

ちなみにMattさんは日本語を勉強しているので声かければ喜んでくれるはずです。

Official Partyで話しかけました

Techouseでは、社会課題の解決に一緒に取り組むエンジニアを募集しております。 ご応募お待ちしております。 jp.techouse.com