Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
標準ライブラリの奥深アップデートを掘り下げよう!
Search
logica / Takuto Nagami
September 03, 2024
Technology
2
780
標準ライブラリの奥深アップデートを掘り下げよう!
2024/9/3 Go 1.23リリースパーティーにて発表した際の資料です。
time / unique / structsパッケージについて、詳細な解説を行っています。
logica / Takuto Nagami
September 03, 2024
Tweet
Share
More Decks by logica / Takuto Nagami
See All by logica / Takuto Nagami
プロポーザル一次〆切に向けて
logica0419
0
29
「海外登壇」という 選択肢を与えるために 〜Gophers EX
logica0419
0
880
Nekko Cloud、 これまでとこれから ~学生サークルが作る、 小さなクラウド
logica0419
2
1.1k
Proposal Challengers 2025 募集説明会
logica0419
1
21
Kubernetesを知る
logica0419
19
6.3k
Resizing Animated GIFs Without CGO or Third-Party Libraries
logica0419
2
42
徹底比較!HA Kubernetes ClusterにおけるControl Plane LoadBalancerの選択肢
logica0419
2
390
外部カンファレンスで登壇しよう! 〜「強い」エンジニアへの一歩を踏み出す〜
logica0419
4
220
kube-vipとkube-proxy置き換えCiliumを積んだ究極のK3sクラスタを建てる
logica0419
4
650
Other Decks in Technology
See All in Technology
データマネジメントのトレードオフに立ち向かう
ikkimiyazaki
6
1.1k
CZII - CryoET Object Identification 参加振り返り・解法共有
tattaka
0
420
分解して理解する Aspire
nenonaninu
2
480
ハッキングの世界に迫る~攻撃者の思考で考えるセキュリティ~
nomizone
13
5.5k
偶然 × 行動で人生の可能性を広げよう / Serendipity × Action: Discover Your Possibilities
ar_tama
1
1.3k
SA Night #2 FinatextのSA思想/SA Night #2 Finatext session
satoshiimai
1
150
Amazon S3 Tablesと外部分析基盤連携について / Amazon S3 Tables and External Data Analytics Platform
nttcom
0
140
ビジネスモデリング道場 目的と背景
masuda220
PRO
9
660
プロダクトエンジニア構想を立ち上げ、プロダクト志向な組織への成長を続けている話 / grow into a product-oriented organization
hiro_torii
1
290
Iceberg Meetup Japan #1 : Iceberg and Databricks
databricksjapan
0
110
明日からできる!技術的負債の返済を加速するための実践ガイド~『ホットペッパービューティー』の事例をもとに~
recruitengineers
PRO
3
490
エンジニアのためのドキュメント力基礎講座〜構造化思考から始めよう〜(2025/02/15jbug広島#15発表資料)
yasuoyasuo
18
7.1k
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Done Done
chrislema
182
16k
Building Applications with DynamoDB
mza
93
6.2k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
30
4.6k
Designing Experiences People Love
moore
140
23k
Producing Creativity
orderedlist
PRO
344
39k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
630
Building an army of robots
kneath
303
45k
Code Reviewing Like a Champion
maltzj
521
39k
Transcript
logica X: @logica0419 GitHub: @logica0419 標準ライブラリの 奥深アップデートを 掘り下げよう!
自己紹介 • logica (ろじか) • 千葉工業大学 情報科学部 情報ネットワーク学科 3年 •
ネットワークコンテンツ研究会 所属 ◦ 数人の自宅サーバーをVPNで繋いでクラウド基盤 作ろうとしてます • 最近、GoLabというイタリアで行われる カンファレンスでの登壇が決まりました
Go 1.23だ!!!
Go 1.23だ!!! イテレータ(range over func)だ!
Go 1.23だ!!! イテレータ(range over func)だ!
ところで…
ところで…
ところで…
ところで…
全部の変更 説明できる人?
説明できる方は 素晴らしい!
今回のアプデ、難しい • そもそも需要が少ない ◦ 問題意識を持つ人が少ない部分へのアプローチ ◦ 特定の課題を解決する上では非常に強力 • 理解するために、事前知識が必要 ◦
特にuniqueとstructsパッケージ ◦ メモリに関する結構深めの知識が必須 でも、理解できるときっと面白い!
今日は 前提知識からしっかり 理解することを目指します! 頑張っていきましょう!
timeの重要な変更 (time.Timer と time.Ticker)
time.Timer / time.Tickerおさらい • time.Timer ◦ 1回のイベントを表す ◦ 指定した時間が過ぎると、Timer.Cから現在時刻が 送られる
• time.Ticker ◦ Timerの繰り返し版 ◦ 指定した間隔で、Ticker.Cから現在時刻が送られ 続ける type Timer struct { C <-chan Time } type Ticker struct { C <-chan Time }
timeの重要な変更 (time.Timer と time.Ticker) 1. Stop()が呼ばれなくてもGCされる
そもそもGCとは?を超簡単に • プログラムの基本的なデータフローはバケツリレー ◦ 関数から関数に引数と戻り値で受け渡す • メモリ内をヒープ・スタックという2つの領域に分けて データを管理する ◦ バケツリレーはスタック
◦ バケツリレーで共有しない ものはヒープ ▪ ポインタで取り出す
ヒープ・スタックの使い分けとGC • スタックだけだと不合理な場合がある ◦ 大きなサイズの構造体は、バケツリレーだと コピーのコストが大きい などなど… • Garbage Collection
(GC) ◦ スタックのデータは関数と寿命が一致するが、 ヒープは溜まる一方 ◦ 使い終わったヒープのデータを検出・削除する プロセスがGC
来年のGo Conferenceの プロポーザルで詳しい話を 出したいと思っています… 応援してください
• 今までのTimer / Tickerは、以下の条件だと使われ ないことが分かっていてもGCされなかった ◦ Timer: Stop()されてない || 時間が過ぎてない
◦ Ticker: Stop()されてない • ↑ のため、関数内でしか使わないTimer / Tickerを 生成したときはdefer Stop()する必要があった • Go 1.23からはしなくても良くなります! Stop()が呼ばれなくてもGCされる
timeの重要な変更 (time.Timer と time.Ticker) 1. Stop()が呼ばれなくてもGCされる 2. channelがバッファ0に
Timer / Tickerのchannel • 今までは1のバッファがあった ◦ Stop()やReset()を呼んだ後でも、呼び出し前に 入れられた値は取り出せてしまう ◦ これがStop()やReset()の使用を難しくしていた
• これからはバッファが0になる ◦ channelから値をすぐに出さなくてもTimer / Tickerが狂うとかはない ◦ Stop()やReset()を呼ぶと値は取り出せなくなる
go.modとasynctimerchan=1 • 今回の挙動が適用されるのは、go.modのgoの行の バージョンが1.23.0以降の時だけ ◦ 古いバージョンを書いていたら、コンパイラが 新しくても古い挙動が適用される • GODEBUG=asynctimerchan=1をつけてビルドすると 古い挙動が適用される(channelもGCも)
◦ Go 1.27までは使える予定らしい
uniqueの追加
uniqueって何? • なんかsliceから重複した値消し去ってくれるとか? • stringの中の同じ文字検知してくれるとか? → 全然違います! uniqueパッケージは、interningという かなり攻めたメモリ使用量の削減手法を Goに実装したもの
です。
interning?
これはinternship
interningとは • 以下のプログラムを考えてみよう func main() { values := make([]int, 2)
values[0] = 10 values[1] = 10 fmt.Println( values[1], values[2], ) }
interningとは • 以下のプログラムを考えてみよう func main() { values := make([]int, 2)
values[0] = 10 values[1] = 10 fmt.Println( values[1], values[2], ) } メモリ使用イメージ
interningとは • 以下のプログラムを考えてみよう func main() { values := make([]int, 2)
values[0] = 10 values[1] = 10 fmt.Println( values[1], values[2], ) } メモリ使用イメージ (同じ値が複数あるの 無駄なのでは…?)
interningとは これを
interningとは これを こうしたい
interningとは これを こうしたい 1つの値にまとめて 容量を削減
interningとは これを こうしたい 1つの値にまとめて 容量を削減 これがinterning
uniqueパッケージ • Handle ◦ interningを実装した型 ◦ 実態はTのポインタだと思えばOK ◦ Value()メソッドで実際の値を引き出せる •
Make() ◦ Handle型を生成するための関数 ◦ もし過去に同じvalueでHandle型が生成されて いたら、その時のポインタを流用する type Handle[T comparable] struct {} func (h Handle[T]) Value() T func Make[T comparable](value T) Handle[T]
使い方 • さっきのプログラムを書き換えてみる func main() { values := make( []unique.Handle[int],
2 ) values[0] = unique.Make(10) values[1] = unique.Make(10) fmt.Println( values[1].Value(), values[2].Value(), ) } func main() { values := make( []int, 2 ) values[0] = 10 values[1] = 10 fmt.Println( values[1], values[2], ) }
使い方 • さっきのプログラムを書き換えてみる func main() { values := make( []unique.Handle[int],
2 ) values[0] = unique.Make(10) values[1] = unique.Make(10) fmt.Println( values[1].Value(), values[2].Value(), ) } メモリ使用イメージ
stringへの特殊な挙動(string interning) • stringは「変更不可能なポインタ」と呼ばれる ◦ ポインタだが、その実体が変更不可 ◦ unsafe.StringData()でアドレスを取得可能 • stringに対してinterningを行うと、このアドレスが
同じ実体に対して揃う ◦ 「string interning」 と呼ばれる
stringへの特殊な挙動(string interning) • 本来interningとstring interningはちょっと違う概念 ◦ interning: 本来はオブジェクトが対象 ◦ string
interning: 文字列型限定 • 今回のuniqueパッケージは、実際は interningとstring interningを同じインターフェース で使えるようにしたもの と言えるかな…?という感じ ◦ Pythonとかも一緒(というかPythonは自動でやる)
使いどころ • 正直そう無いかもしれないが、効くところには効く ◦ 同じ値を色んな箇所で何度も使う場合 ◦ ↑ 特に値がstringや容量が大きい構造体の場合 • net/netipの例
- IPアドレスのプロパティをinterning type Addr struct { addr uint128 z unique.Handle[addrDetail] } type addrDetail struct { isV6 bool // IPv4 is false, IPv6 is true. zoneV6 string // != "" only if IsV6 is true. }
structsの追加
structsって何? • structに対して便利な機能を提供してくれる ユーティリティーだと思ってた! → 全然違います! structsパッケージは、structに関して、 メモリレイアウトのような言語仕様に関わる プロパティを変更できるようにするものです。
structsパッケージ type HostLayout struct {} • 今回追加された変更可能プロパティは1つ • HostLayout ◦
埋め込まれた構造体のメモリレイアウトが、ホスト OSのC言語ABIに則ることを保証する • 使い方 type Example struct { _ structs.HostLayout // こんな感じで差し込むだけ Value string }
ABI? メモリレイアウト? なんじゃそりゃ? みんな「?」だと思うので、1つずつ確認しましょう
ABI • Application Binary Interface (ABI) ◦ OSとバイナリ / バイナリ同士の約束ごと
◦ バイナリの中で変数がどのようにメモリに入るか / 関数がどのように呼ばれるか などを規定する ◦ CGOで特に重要(Goから直にCバイナリを呼ぶので) • 参考: Application Programming Interface (API) ◦ アプリケーション同士の約束事 ◦ どんな機能を持ち、どんな風に使うかを定義する
ABI • Goは独自のABIを持っている ◦ https://go.googlesource.com/go/+/refs/heads/ dev.regabi/src/cmd/compile/internal-abi.md • Cも、コンパイラごと(GNUとかmuslとか)にABIを 持っている ◦
なので、ホストOSごとにCのABIは異なる ◦ 「ホストOSのC言語ABI」はこのこと
メモリレイアウト • ABIの中で、特に変数がどんな風にメモリに入るかを 定義している部分 ◦ 各型のバイト数やアライン、 structのメモリへの積み方 などが書いてある • Goの場合の例
◦ 型のバイト数は→ ◦ structはフィールド順
改めてstructsパッケージ type HostLayout struct {} • 今回追加された変更可能プロパティは1つ • HostLayout ◦
埋め込まれた構造体のメモリレイアウトが、ホスト OSのC言語ABIに則ることを保証する • 使い方 type Example struct { _ structs.HostLayout // こんな感じで差し込むだけ Value string }
なぜstructsパッケージが必要なのか • 元々Goのメモリレイアウトの実装は、ホストOSの C言語ABIに強く依存している ◦ CGOを使うとき、ホストOSのC言語ABIと揃って いないと壊れる可能性がある ←これ、稀では? • structsパッケージがあると、メモリレイアウトを
崩したとき壊れるstructを明示できるため、メモリ レイアウトを崩すメモリ最適化ができる! ◦ structをフィールド順に従わず配置する など
すなわち、HostLayoutは 付けた物を変えるんじゃなく 付けない物を変える下準備です! これだけ皆覚えて帰って下さい
まとめ と 宣伝
「自分使わないな」って機能も 深堀りすると面白いって 思ってもらえたら幸いです! 超スピードで駆け抜けてしまって申し訳ないです…
“Go Far”s Japan プロジェクト (仮) • 僕の人脈・ノウハウ・やる気全てを動員して、日本の Gopherたちを海外カンファレンスに引き込んでいく プロジェクトをやりたいと思っています! ◦
Gophers Japanと協力してやりたいですがまだ 企画書を書いていないです • やりたいこと ◦ 国内英語 / 日本語同時発表カンファレンス ◦ プロポーザルのクオリティUP支援 などなど!
ありがとう ございました
参考文献たち • https://go.dev/doc/go1.23 • https://pkg.go.dev/ • https://pythontutor.com/ • https://github.com/golang/go/issues/62483 •
https://future-architect.github.io/articles/20240719a/ • https://ikorin2.hatenablog.jp/entry/2019/12/16/195847 • https://qiita.com/kahibella/items/cd8b48f1d2c109b76e10 • https://speakerdeck.com/ymotongpoo/memory-manageme nt-in-go • https://cs.opensource.google/go/go/+/refs/tags/go1.23. 0:src/net/netip/netip.go • https://github.com/golang/go/issues/66408 • https://satoru-takeuchi.hatenablog.com/entry/2020/03/ 26/011858