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
encoding/json/v2のUnmarshalはこう変わった:内部実装で見る設計改善
Search
Hiroki Kurasawa
February 21, 2026
Programming
0
100
encoding/json/v2のUnmarshalはこう変わった:内部実装で見る設計改善
Go Conference mini in Sendai 2026 のLT枠「encoding/json/v2のUnmarshalはこう変わった:内部実装で見る設計改善」で発表した登壇資料です。
Hiroki Kurasawa
February 21, 2026
Tweet
Share
More Decks by Hiroki Kurasawa
See All by Hiroki Kurasawa
Go1.26 go fixをプロダクトに適用して困ったこと
kurakura0916
0
320
Other Decks in Programming
See All in Programming
Claude Codeと2つの巻き戻し戦略 / Two Rewind Strategies with Claude Code
fruitriin
0
200
社内規程RAGの精度を73.3% → 100%に改善した話
oharu121
12
7.2k
今、アーキテクトとして 品質保証にどう関わるか
nealle
0
200
Rubyと楽しいをつくる / Creating joy with Ruby
chobishiba
0
200
24時間止められないシステムを守る-医療ITにおけるランサムウェア対策の実際
koukimiura
2
180
手戻りゼロ? Spec Driven Developmentとは@KAG AI week
tmhirai
1
100
Head of Engineeringが現場で回した生産性向上施策 2025→2026
gessy0129
0
200
浮動小数の比較について
kishikawakatsumi
0
360
TROCCOで実現するkintone+BigQueryによるオペレーション改善
ssxota
0
120
DSPy入門 Pythonで実現する自動プロンプト最適化 〜人手によるプロンプト調整からの卒業〜
seaturt1e
1
440
Claude Code の Skill で複雑な既存仕様をすっきり整理しよう
yuichirokato
1
220
Beyond the Basics: Signal Forms
manfredsteyer
PRO
0
110
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
432
66k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
What's in a price? How to price your products and services
michaelherold
247
13k
Design in an AI World
tapps
0
160
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
200
The SEO Collaboration Effect
kristinabergwall1
0
380
ラッコキーワード サービス紹介資料
rakko
1
2.5M
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
110
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
570
Designing Experiences People Love
moore
143
24k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.4k
Transcript
encoding/json/v2のUnmarshalはこう変わった ~内部実装で見る設計改善 ~ Go Conference mini in Sendai 2026 @kurasawah
1
⾃⼰紹介 • 倉澤 大樹(@kurasawah) ◦ 株式会社ZOZOで検索機能を開発しています ◦ GoとElasticsearchが好きです 2
このテーマを話そうと思ったきっかけ • encoding/json/v2はGo1.25で実験的に追加された • v2では「処理速度」「メモリ使用量」「アロケーション回数」 「エラー内容」が改善された • 「なぜ改善されたのか?」を内部設計から理解したくなった • 調べてみると、自分のコードにも活かせそう
3
今日話す4つの改善ポイント 1. パッケージ分離 2. エラーの原因特定 3. オブジェクトの再利用(sync.Pool) 4. 効率的なバッファ管理 4
v2のUnmarshal: 4つの改善ポイント 5 func Unmarshal(in []byte, out any, opts ...Options)
(err error) { dec := export.GetBufferedDecoder(in, opts...) defer export.PutBufferedDecoder(dec) xd := export.Decoder(dec) err = unmarshalDecode(dec, out, &xd.Struct, true) return err } コード 改善ポイント export オブジェクト パッケージ分離 err エラーの原因特定 Get/PutBufferedDecoder オブジェクトの再利用(sync.Pool) Decoder 構造体 効率的なバッファ管理 src/encoding/json/v2/arshal.go
改善点1: パッケージ分離 v1: encoding/json 1パッケージに全機能が混在 v2: jsontext(構文層)+ json(意味層)に分離 パッケージ 層
例 jsontext 構文層 { , "name" , : , "Alice" ... json 意味層 "Alice" → User.Name なぜ良いか • 責務が分かれ、変更の影響範囲が限定される • 構文層(jsontext)を単独で利用できる 6
{"name":"Alice","age":"thirty"} → User.Ageはint型なのでエラー v1: cannot unmarshal string into Go struct
field User.Age v2: cannot unmarshal JSON string into Go int within "/age" 改善点2: エラーの原因特定 なぜ原因特定が容易か • JSONPointerで「どこで」、JSONKindで「何型が」失敗したか分かる &SemanticError{ … JSONPointer: "/age" , // どこで JSONKind: '"', // JSON型(string) GoType: reflect.TypeOf(int(0)), // 期待した型 ... } src/encoding/json/v2/errors.go
• v1: 毎回ゼロ値初期化 → 呼び出しごとにメモリ確保 • v2: GetBufferedDecoder PutBufferedDecoder でプール管理
なぜ良いか : 高頻度呼び出し時のアロケーションとGCへの負担を削減 改善点3: オブジェクトの再利用 (sync.Pool) 1回目: Unmarshal({"name":"Alice",...}) ↓ Decoder取得 ↓ 処理 ↓ Poolへ戻す 2回目: Unmarshal({"name":"Bob",...}) ↓ 同じDecoder再利用 8
なぜ良いか : buf[prevStart:prevEnd] でコピーなしに前回値へアクセス可能 例: {"name":"Alice","age":30} を "Alice" まで読んだ時 →
buf[prevStart:prevEnd] = "Alice" decodeBuffer — 1つの []byte を論理的に4分割 改善点4: 効率的なバッファ管理 9 type decodeBuffer struct { … buf []byte // 入力全体を保持するバッファ prevStart int // 前回読んだ値の開始位置 prevEnd int // 前回読んだ値の終了位置 rd io.Reader // 入力元(ストリーミング対応) } src/encoding/json/jsontext/decode.go
まとめ • パッケージ分離 : jsontext + jsonによる責務の分離 • エラーの原因特定 :
SemanticErrorによる構造化エラー • オブジェクトの再利用 : sync.Poolによるアロケーション削減 • 効率的なバッファ管理 : decodeBufferによるコピーなしアクセス 10