萌えハッカーニュースリーダー

2025/04/07 22:30 A surprising enum size optimization in the Rust compiler

出典: https://jpfennell.com/posts/enum-type-size/
hakase
博士

やっほー、ロボ子! 今日もRustのメモリレイアウトについて勉強するのじゃ!

roboko
ロボ子

博士、こんにちは! メモリレイアウト、奥が深くて面白いですよね。今日もよろしくお願いします。

hakase
博士

今日はEnumじゃ! Enumって、指定されたバリアントのどれか一つの値を持つ型のことだぞ。

roboko
ロボ子

はい、Enumは列挙型のことですね。例えば、`enum Color { Red, Green, Blue }` のように定義できますね。

hakase
博士

そうそう! で、Enumのメモリ表現じゃが、これがまた面白いんじゃ。基本的には、最大のペイロードのサイズに、どのバリアントかを示すタグを足したサイズになるぞ。

roboko
ロボ子

タグというのは、どのバリアントが格納されているかを示す識別子のことですね。

hakase
博士

`Foo`型を例に見てみるのじゃ。`Foo`は整数か文字のバリアントを持っていて、それぞれのペイロードは4バイトじゃ。タグには最低1バイト必要じゃが、アライメントの関係で4バイトになるから、全体のサイズは8バイトになる。

roboko
ロボ子

アライメントというのは、メモリ上のアドレスを特定の境界に揃えることですね。4バイトのアライメントだと、アドレスが4の倍数になるように調整されるんでしたっけ。

hakase
博士

その通り! そして、このコンピュータはリトルエンディアンだから、最下位バイトが最初に来るぞ。

roboko
ロボ子

リトルエンディアンだと、例えば32ビットの整数`0x12345678`は、メモリ上では`78 56 34 12`の順で格納されるんですね。

hakase
博士

その通り! `Foo::Int`にはタグ0、`Foo::Char`にはタグ1が割り当てられるんじゃ。

roboko
ロボ子

なるほど。タグでどのバリアントかを区別するんですね。

hakase
博士

そして、ニッチ最適化! これはEnumのサイズを小さくするテクニックの一つじゃ。バリアントの一つだけがペイロードを持つ場合に使えるぞ。

roboko
ロボ子

ニッチ最適化ですか。具体的にはどのような場合に適用されるんですか?

hakase
博士

`Option<char>`型が良い例じゃ。`char`は4バイトなのに、`Option<char>`も4バイトで済むんじゃ!

roboko
ロボ子

えっ、どうしてですか? `Option`は`Some(char)`か`None`のどちらかですよね。タグが必要なので、`char`の4バイトに加えてタグの分のサイズが必要になるはずでは…?

hakase
博士

そこがミソなのじゃ! `char`の有効な値の範囲は4バイトで表現できるすべての値よりも狭いから、コンパイラが無効なビットパターンをニッチとして使うんじゃ。だから、タグなしでEnumの値を表現できるのじゃ!

roboko
ロボ子

なるほど! `char`で表現できない値、例えば`0x00110000`を`None`として使うんですね。

hakase
博士

そう! そして、ネストされたEnumでは、さらに最適化が進むんじゃ。

roboko
ロボ子

ネストされたEnumですか。例えば、次のような場合ですね。

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search