こんにちは、2024年に新卒で入社し、ジョブハウスでバックエンドエンジニアをしているププです。
本記事では、1日目のMatt Valentine-Houseさん(@eightbitraptor)によるセッション、Stringの割り当てに関するバグと解決の話について紹介させていただきます。
Strings! Interpolation, Optimisation & Bugs
まず、Stringのメモリ割り当ての説明ですが、Stringは文字列の長さによって割り当てが違うということを知ってますか?
40bytesのヒープ領域に保存されてるものですが、実は16bytesはmetadataとポインタの情報が格納されており、残りの24bytesにStringの内容が入れられています。
それ以上の大きさのStringの場合は、そのサイズに応じて、80、120、320bytesでヒープ領域に格納されます。
したがって、Stringをconcatする際はその新しいStringのヒープ領域を調整する必要があります。
例えば40bytesのStringと80bytesのStringの場合、80または160bytesにする必要があります。
しかし、ここにはバグが潜んでおり、"slot_size"が正確に計算されない事がわかっています。
それに加えてembeddingしないことから、パフォーマンスにも悪い影響を与えていました。
Mattさんはこのバグを解決するために、concatのコードを見て調査しました。
すると、MIN_PRE_ALLOC_SIZE
という定数を発見し、その値が48になっていることがわかりました。
「このマジックナンバーは何のためだろう?なぜ48なのだろう?」と思いました。
この流れで元のコミットのコメントを確認してみたら、理由がわかりました。
その時代のパソコンの性能がボトルネックとなり、必要な処理であったようです。
現代の実行環境では必要のない処理であることがわかったので、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
感想
技術的にも非常に面白いセッションでしたが、開発への取り組み方に関しても、参考になる箇所がありました。
- 自分の理解のためにも、想像で補わず、コードを読んで実装を追うべきだ。
- 自分のためでなく、将来の人のために、コミットメッセージはしっかりと書いた方がいい。
私も今まで書いたコミットメッセージは良くないものが多いため、この話を聞いた今からはしっかりと書こうと思いました。
ちなみにMattさんは日本語を勉強しているので声かければ喜んでくれるはずです。
Techouseでは、社会課題の解決に一緒に取り組むエンジニアを募集しております。 ご応募お待ちしております。 jp.techouse.com