15.2K Views
April 17, 24
スライド概要
GoDay 出張編 @ DeNA TechCon 2024
https://dena.connpass.com/event/308853/
DeNA が社会の技術向上に貢献するため、業務で得た知見を積極的に外部に発信する、DeNA 公式のアカウントです。DeNA エンジニアの登壇資料をお届けします。
ジェネリクスの実装方針を知ろう ~ GoDay 出張編 ~ 葉狩 勇人 IT本部 IT基盤部 第四グループ 株式会社ディー・エヌ・エー © DeNA Co., Ltd. 1
自己紹介 葉狩 勇人 IT本部 IT基盤部 第四グループ 陸上自衛官として5年間迫撃 砲というのを撃つ 内定者インターン(2022.02 ~) ● 日比谷音楽祭2022 ● ENG室 ● 日比谷音楽祭2023 現在は大規模ゲームタイトルのインフラを運用中 © DeNA Co., Ltd. 2
ジェネリクス便利ですよね © DeNA Co., Ltd. 3
コードはスッキリしたけれど…? バイナリサイズが 375 byte も増えている © DeNA Co., Ltd. 4
コードはスッキリしたけれど…? なぜバイナリサイズ が増えたのだろう? バイナリサイズが 375 byte も増えている もっとコードが 増えたら…? © DeNA Co., Ltd. 5
成り立ちを知ろう! ジェネリクスは便利だが、 思わぬ落とし穴に落ちないためにも成り立ちを知ることが大事 © DeNA Co., Ltd. 6
どのように型解決される? © DeNA Co., Ltd. 7
Go のジェネリクス実装方針 Go 1.18 で採用された仕組みは Dictionaries and Gcshape Stenciling 組み」と呼びます。長いので…) (以降は 「Go のジェネリクスの仕 「Stenciling」「辞書」というジェネリクスの実装方針を組み合わせたもの © DeNA Co., Ltd. 8
Go のジェネリクス実装方針 - Stenciling とは コンパイル時に、呼び出しに応じてそれぞれの 型ごとの具体的な実装を用意する 例えば、右のジェネリクス関数f から f1, f2 という具体的な型を持つ関数が生成さ れる © DeNA Co., Ltd. 9
Go のジェネリクス実装方針 - Stenciling のメリット・デメリット メリット ● 実装が単純 ● 具体的な型を持った関数を生成するので実行効率が損なわれない デメリット ● 呼び出しごとに具体的な型を持つ関数が生成されるため、バイナリサイズが膨大になる © DeNA Co., Ltd. 10
Go のジェネリクス実装方針 - 辞書とは ジェネリクス関数から処理の実体 と型情報を含む辞書が生成される プログラム実行時に辞書を使って 型解決をする © DeNA Co., Ltd. 11
Go のジェネリクス実装方針 - Go 1.18 での辞書の実装 © DeNA Co., Ltd. 12
Go のジェネリクス実装方針 - 辞書のメリット・デメリット メリット ● Stenciling と異なり型情報以外の重複を避けられるためバイナリサイズを抑えられる デメリット ● 辞書を介して動作するため、実行速度が低下する可能性がある © DeNA Co., Ltd. 13
Go のジェネリクス実装方針 - 「Stenciling」と「辞書」のまとめ 実行効率とバイナリサイズの増加がトレードオフになっている メリット Stenciling 辞書 © DeNA Co., Ltd. デメリット ● 実行効率が損なわれない ● バイナリサイズが膨大になる ● 型情報以外の重複を避けられるた ● 辞書を介して動作するため、実行速 めバイナリサイズを抑えられる 度が低下 14
Go のジェネリクス実装方針 - Go のジェネリクスの仕組み 辞書と Stenciling のハイブリッド方式 辞書をベースに Gcshape Stenciling という概念を使うことで以下の利点がある ● 単純な辞書のデメリットである実行速度の低下を抑える ● 辞書ベースなので Stenciling と比べてバイナリサイズが抑えられる © DeNA Co., Ltd. 15
Go のジェネリクス実装方針 - Gcshape とは その型が GC(ガベージコレクタ)からどう見えるか ● 型のサイズは? ● どんなメモリ配置? ● … 君は go.shape.int © DeNA Co., Ltd. GC 16
Go のジェネリクス実装方針 - Gcshape があるとどうなるの? 異なる型でも Gcshape が同じであれば同じ辞書インスタンスを共有できる 辞書インスタンスの数が減るので型チェックや型変換のコストが削減できる 実行時のオーバーヘッドが減少して実行効率が高まる ふたりとも go.shape.int ね! MyInt © DeNA Co., Ltd. int GC 17
Go のジェネリクス実装方針 - MyInt と Int を使った Gcshape の検証 異なる型でも同じ Gcshape として扱われ るのか?という疑問の解消のため 右のコードをコンパイルして go の objdump で実行バイナリを見てみる © DeNA Co., Ltd. 18
Go のジェネリクス実装方針 - Gcshape の検証結果 MyInt と int の異なる型同士で同じ Gcshape を使っている 同じ Gcshape が使われている © DeNA Co., Ltd. 19
Go のジェネリクス実装方針 - 実装方針の比較 Go での実装は「辞書」「Stenciling」のデメリットを抑えている 実行効率 Stenciling 辞書 Go での実装 © DeNA Co., Ltd. バイナリサイズ ● 実行効率が損なわれない ● バイナリサイズが膨大になる ● 辞書を介して動作するため、実行速 ● 型情報以外の重複を避けられるためバ 度が低下 ● 辞書よりも効率化されているため、 大きくは実行効率が損なわれない イナリサイズを抑えられる ● 型情報以外の重複を避けられるためバ イナリサイズを抑えられる 20
Go のジェネリクス実装方針 - まとめ ● Go 1.18 で採用されたジェネリクスの実装は「Stenciling」「辞書」を組み合 わせたもの ○ Gcshape が同じであればインスタンス化された辞書を共有できるので、 辞書周りのコストが削減できる ● バイナリサイズが大きくなる原因は型情報を含む辞書を保持するため ● 闇雲にジェネリクス化を進めるとバイナリサイズは増えるが、急激に増える ような実装にはなっていない © DeNA Co., Ltd. 21
最後に ● Go のジェネリクスはまだリリースから 2 年ほどしか経過していない若い機 能 ● これから大きな変更や方針の転換があるかもしれない ● 予期せぬ落とし穴に引っかからないためにも、ぜひ一緒にジェネリクスの変 更を追いかけて行きましょう! © DeNA Co., Ltd. 22
参考資料 ● proposal/design/generics-implementation-dictionaries-go1.18.md at master ● generics-implementation-dictionaries.md - golang/proposal ● generics-implementation-gcshape.md - golang/proposal ● proposal/design/generics-implementation-stenciling.md at master © DeNA Co., Ltd. 23
© DeNA Co., Ltd. 24