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
Takuto Nagami
September 03, 2024
Technology
2
920
標準ライブラリの奥深アップデートを掘り下げよう!
2024/9/3 Go 1.23リリースパーティーにて発表した際の資料です。
time / unique / structsパッケージについて、詳細な解説を行っています。
Takuto Nagami
September 03, 2024
Tweet
Share
More Decks by Takuto Nagami
See All by Takuto Nagami
今こそ学びたいKubernetesネットワーク ~CNIが繋ぐNWとプラットフォームの「フラッと」な対話
logica0419
9
810
キャリア科目では教えてくれない、就活を生き抜く法則
logica0419
2
250
歴史から学ぶ、Goのメモリ管理基礎
logica0419
17
3.5k
【2025改訂版】ITエンジニアとして知っておいてほしい、電子メールという大きな穴
logica0419
2
160
Fundamentals of Memory Management in Go: Learning Through the History
logica0419
1
140
GopherCon Tourのつくりかた
logica0419
2
120
Go言語はstack overflowの夢を見るか?
logica0419
2
820
あなたの言葉に力を与える、演繹的なアプローチ
logica0419
1
280
GC25 Recap+: Advancing Go Garbage Collection with Green Tea
logica0419
3
990
Other Decks in Technology
See All in Technology
ソフトウェアアーキテクトのための意思決定術: Create Decision Readiness—The Real Skill Behind Architectural Decision
snoozer05
PRO
27
7.6k
ヘルシーSRE
tk3fftk
2
190
なぜAIは組織を速くしないのか 令和の腑分け
sugino
80
50k
男(監査)はつらいよ - Policy as CodeからAIエージェントへ
ken5scal
4
660
トラブルの大半は「言ってない」x「言ってない」じゃねーか!!
ichimichi
0
210
Introduction to Sansan Meishi Maker Development Engineer
sansan33
PRO
0
360
ローカルでLLMを使ってみよう
kosmosebi
0
210
失敗できる意思決定とソフトウェアとの正しい歩き方_-_変化と向き合う選択肢/ Designing for Reversible Decisions
soudai
PRO
8
1.4k
組織のSREを推進するためのPlatform EngineeringとEKS / Platform Engineering and EKS to drive SRE in your organization
chmikata
0
150
「データとの対話」の現在地と未来
kobakou
0
970
オンプレとGoogle Cloudを安全に繋ぐための、セキュア通信の勘所
waiwai2111
3
1k
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
15
95k
Featured
See All Featured
Navigating Weather and Climate Data
rabernat
0
130
Become a Pro
speakerdeck
PRO
31
5.8k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Darren the Foodie - Storyboard
khoart
PRO
3
2.7k
How to Think Like a Performance Engineer
csswizardry
28
2.5k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Site-Speed That Sticks
csswizardry
13
1.1k
Agile that works and the tools we love
rasmusluckow
331
21k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
140
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8.7k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
130
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
1
1.3k
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