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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
matumoto
July 23, 2024
Technology
0
380
いまいちどスライスの 挙動を見直してみる
DMM.go#8で登壇した際の発表資料です
connpass
-
https://dmm.connpass.com/event/322113/
matumoto
July 23, 2024
Tweet
Share
More Decks by matumoto
See All by matumoto
testingを眺める
matumoto
1
180
sync/v2 プロポーザルの 背景と sync.Pool について
matumoto
0
650
Goトランザクション処理
matumoto
1
71
Go1.22のリリース予定の機能を見る
matumoto
0
77
GoのUnderlying typeについて
matumoto
0
220
Typed-nilについて
matumoto
0
350
GoのType Setsという概念
matumoto
0
40
GoのRateLimit処理の実装
matumoto
0
460
Webプッシュ通知触ってみた
matumoto
0
39
Other Decks in Technology
See All in Technology
大規模サービスにおける レガシーコードからReactへの移行
magicpod
1
130
A Gentle Introduction to Transformers
keio_smilab
PRO
1
120
Agentic Software Modernization - Back to the Roots (Zürich Agentic Coding and Architectures, März 2026)
feststelltaste
1
170
「ヒットする」+「近い」を同時にかなえるスマートサジェストの作り方.pdf
nakasho
0
110
研究開発部メンバーの働き⽅ / Sansan R&D Profile
sansan33
PRO
4
22k
Bill One 開発エンジニア 紹介資料
sansan33
PRO
5
18k
メタデータ同期に潜んでいた問題 〜 Cache Stampede 時の Cycle Wait を⾒つけた話
lycorptech_jp
PRO
0
150
男(監査)はつらいよ - Policy as CodeからAIエージェントへ
ken5scal
5
730
LINEヤフーにおけるAI駆動開発組織のプロデュース施策
lycorptech_jp
PRO
0
400
プロジェクトマネジメントをチームに宿す -ゼロからはじめるチームプロジェクトマネジメントは活動1年未満のチームの教科書です- / 20260304 Shigeki Morizane
shift_evolve
PRO
1
110
製造業ドメインにおける LLMプロダクト構築: 複雑な文脈へのアプローチ
caddi_eng
1
450
Exadata Database Service on Dedicated Infrastructure(ExaDB-D) UI スクリーン・キャプチャ集
oracle4engineer
PRO
7
7.1k
Featured
See All Featured
Agile that works and the tools we love
rasmusluckow
331
21k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
67
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.3k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
67
37k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Test your architecture with Archunit
thirion
1
2.2k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
260
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.3k
How to Ace a Technical Interview
jacobian
281
24k
Embracing the Ebb and Flow
colly
88
5k
Paper Plane (Part 1)
katiecoart
PRO
0
5.1k
Transcript
© DMM CONFIDENTIAL いまいちどスライスの 挙動を見直してみる DMM.go #8 24新卒 松本響輝(matumoto) 2024-07-23
発表の目的 • スライスがどう作られているのか把握する • 気をつけたい罠とその対策を理解する 2 スライスに関して改めて 詳しくなってもらいたい!
目次 • 基本操作のおさらい • スライスの実体 • 気をつけること • Tips 3
基本操作のおさらい 4
スライスの宣言 • []T で型 T のスライスになる 5
スライスのリテラル • []T{x1, x2, … , xn} で型 T の要素をn個もつスライスになる
6
スライス式 • a[low:high] でスライスを構築できる 7
スライスの実体 8
スライスがどう実装されているか • 配列へのポインタ、長さ、容量 を持った構造体 9 引用:https://github.com/golang/go/blob/master/src/runtime/slice.go
配列を参照している 10 3 1 4 1 5 x := []int{3,1,4,1,5}
y := x[1:3] ptr len:5 cap:5 ptr len:2 cap:4 [5]int []int []int
ポインタの値をコピー • y := x はポインタの値がコピーされる 11 3 1 4
1 5 x := []int{3,1,4,1,5} y := x ptr len:5 cap:5 ptr len:5 cap:5 [5]int []int []int
容量 (capacity) はどう増えるか • append関数で要素を追加するとき、長さや容量が増えていく 12 x := []int{3,1,4,1,5} ptr
len:5 cap:5 x = append(x, 10, 11) len:7 cap:10 ptr
容量 (capacity) はどう増えるか • 元が256より小さい場合: 2倍ずつ増える • 元が256以上の場合: 1.25倍+192ずつ増える •
192足すのは256付近でもスムーズに増やすため 13 例. capacityを256→350 にしたい +192なし:2回 • 256 * 1.25 = 320 • 320 * 1.25 = 400 +192あり:1回 • 256 * 1.25 + 192 = 512 詳細:https://github.com/golang/go/blob/master/src/runtime/slice.go#L289
気をつけること 14
今回は2つ紹介 15 要素の変更 a[0] = 10 メモリ管理 return a[:3]
1.要素の変更 16
「1.要素の変更」を正しく使っている例 17 引用元:https://github.com/golang/go/blob/master/src/slices/zsortordered.go slices 標準パッケージでのソート処理
「1.要素の変更」の使いどころ 18 • 副作用のある関数で使う • パフォーマンス的に都合が良い場合 • sort, swap •
※ただし、一般的なWebアプリケーション開発ではDB処理などの方が重くなりが ちなので、変数のコピーコストなどは無視することが多いです
「1.要素の変更」の対策 19 • linterで検知する • go-reassignでトップレベル変数への再代入の検知(golangci-lintあり) • goboundcheckで境界チェック • なお、関数が持つ仮引数への再代入検知を行う、というようなlinterは見つけられ
ませんでした(作ることはできそうです) • レビューで気づく • a[i] = 0 みたいな文があったら注意です
2.余分なメモリ参照 • スライスが参照している限り、配列を保持し続ける 20 0 0 0 0 0 x
:= make([]int, 0, 1000) x = x[:3:3] ptr len:3 cap:3 [1000]int []int … 1000要素分メモリが確保されたまま
「2.余分なメモリ参照」のわるい例 • 読み取ったファイル全体は保持されたまま 一部改変して引用:https://go.dev/blog/slices-intro 21
「2.余分なメモリ参照」を改善した例 • 必要な分だけメモリを再確保している 一部改変して引用:https://go.dev/blog/slices-intro 22
「2.余分なメモリ参照」の対策 • 静的解析での検知は難しい • 実行時の挙動であるため厳密に検知できない • レビューで気づく • スライスを受け取って部分スライスを返している関数などに注意 •
regexpパッケージの結果をそのまま返している部分など • 例. return digitRegexp.Find(a) 23
Tips スライスに関するTips 24
sync.Poolによる使い回し • リクエストごとにスライスを作る...というのですら高速化したい • sync.Poolを用いてメモリ領域を使い回すのがよくある手法 • これをラップしたbytebufferpoolというライブラリがある • fasthttpなどで使用されている 25
fasthttpでの例 • fasthttpではレスポンスボディを使い回している 26 引用:https://github.com/valyala/fasthttp/blob/master/http.go
まとめ 27
まとめ • スライスは配列を参照するポインタを持っている • 要素の変更や余分なメモリ参照は気をつけよう • sync.Poolでメモリを使いまわせる 28
ご清聴ありがとうございました!