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
range over funcの使い道と非同期N+1リゾルバーの夢 / about a ran...
Search
mackee
December 13, 2024
Programming
0
640
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
kamakura.go #7
mackee
December 13, 2024
Tweet
Share
More Decks by mackee
See All by mackee
ワンバイナリWebサービスのススメ
mackee
10
7.8k
tanukistack ライブコーディング / tanukistack live-coding
mackee
0
100
perl for shell, awk and sed programmers
mackee
2
2.2k
今更GoのWebフレームワークを作ろうとしているワケ / Why am I trying to create a Go web framework now?
mackee
1
610
database/sqlでNullを扱う歴史とsql.Null[T]の登場 / sql.Null[T] history
mackee
0
500
マイクロサービス化を利用した Goへの移行事例
mackee
0
630
PerlでつくるフルスクラッチWebAuthn/パスキー認証 / Demonstration of full-scratch WebAuthn/Passkey Authentication written in Perl
mackee
3
4.5k
SRE定例やその辺の取り組みをアプリケーションエンジニア目線で語る / "Observe" about SRE Meeting by Application Engineer
mackee
0
1.9k
TinyGoで使えるORM sqllaの 紹介とTinyGoで使えるようにするための工夫
mackee
0
1.5k
Other Decks in Programming
See All in Programming
Is Xcode slowly dying out in 2025?
uetyo
0
110
Spring gRPC で始める gRPC 入門 / Introduction to gRPC with Spring gRPC
mackey0225
2
520
Beyond Portability: Live Migration for Evolving WebAssembly Workloads
chikuwait
0
380
Effect の双対、Coeffect
yukikurage
5
1.4k
生成AIコーディングとの向き合い方、AIと共創するという考え方 / How to deal with generative AI coding and the concept of co-creating with AI
seike460
PRO
1
320
ASP.NETアプリケーションのモダナイズ インフラ編
tomokusaba
1
380
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
760
ドメインモデリングにおける抽象の役割、tagless-finalによるDSL構築、そして型安全な最適化
knih
11
1.9k
社内での開発コミュニティ活動とモジュラーモノリス標準化事例のご紹介/xPalette and Introduction of Modular monolith standardization
m4maruyama
1
130
来たるべき 8.0 に備えて React 19 新機能と React Router 固有機能の取捨選択とすり合わせを考える
oukayuka
2
810
業務自動化をJavaとSeleniumとAWS Lambdaで実現した方法
greenflagproject
1
120
Create a website using Spatial Web
akkeylab
0
290
Featured
See All Featured
Six Lessons from altMBA
skipperchong
28
3.8k
Into the Great Unknown - MozCon
thekraken
39
1.8k
Side Projects
sachag
455
42k
Optimizing for Happiness
mojombo
379
70k
Automating Front-end Workflow
addyosmani
1370
200k
Code Review Best Practice
trishagee
68
18k
The Language of Interfaces
destraynor
158
25k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
4
200
Being A Developer After 40
akosma
90
590k
Visualization
eitanlees
146
16k
Documentation Writing (for coders)
carmenintech
71
4.9k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Transcript
range over funcͷ͍ಓͱ ඇಉظN+1Ϧκϧόʔͷເ @mackee_w
Δਓ • X: @mackee_w • GitHub: @mackee • ໘ന๏ਓΧϠοΫ •
όοΫΤϯυ & SRE • ࠷ۙRAGύΠϓϥΠϯͳͲΛࢼ࡞ ͍ͯ͠·͢
range over func͓͞Β͍ + ͍ಓ
Go 1.23 Release NotesΑΓ
ͬ͘͟Γ range over ** Go language specΑΓ
ͬ͘͟Γrange over func • for range … ͷ … ʹೖΕΒΕΔͭͰɺҙͷڍಈΛ͢Δ͕ͭ࡞ΕΔΑ͏
ʹͳΓ·ͨ͠Α • ݴޠઃܭଆͷҙਤ: ෮ॲཧͷҰൠԽ͞Εͨॲཧύλʔϯɺͭ·ΓΠςϨʔ λʔΛݴޠػೳͱͯ͠ΈࠐΜͩ • *database/sql.Rows *bu fi o.ScannerͳͲΠςϨʔλʔΛಠࣗʹ࣮͠ ͍ͯΔ(ͦͯͦ͠ΕͧΕΠϯλʔϑΣΠε͕ҧ͏) • ͜ΕΒΛେ౷Ұ͢Δҙਤ͕͋ΔͷͰͳ͍͔(ཁग़య)
ͬ͘͟Γ͍ํ
iter.Seqࣗ࡞ͯ͠ྑ͍ • ҙͷྻจࣈྻΛϧʔϓ͝ͱʹ ੜ͠ଓ͚Δ܅࡞ΕΔ • ଞͷrange over **ͱҧ͍ɺແݶʹ Λు͖ग़͢ͷ࡞ΕΔ •
👉ͷྻΛՃ͍ͯͯ͠͠Δ
օ͞Μ͕͙͢ʹ͑Δศརؔ slices.Chunk
iter.Seqผʹfor rangeͰΘͳͯ͘ྑ͍ • iter.Seq slices.Collect ͰεϥΠεʹมͰ͖Δ • ແݶʹΛుͭ͘ऴΘΒͳ͍ͷͰҙ •
εϥΠεͷΑ͏ͳσʔλྻΛදݱ͢ΔσʔλΛ͞ΒʹநԽͨ͠ܕͱݴ͑Δ • github.com/BooleanCat/go-functional/v2/it ʹศརϢʔςΟϦςΟ͕ؔ͋Δ • ͍ΘΏΔ github.com/samber/lo ͷ iter.Seq/iter.Seq2൛ • it.Map/it.Map2, it.Filter/it.Filter2 ͳͲ • x/exp/xiter ύοέʔδʹಉछͷ͕ؔೖΔ͜ͱ͕ٞ͞Ε͍ͯΔ
ࠓ·Ͱͷ + ͬͱதͷ͕ҎԼͷεϥΠυ ʹ͋Δ • Go Conference 2024: ΠςϨʔλʹΑͬͯGoͲ͏มΘΔͷ͔ •
https://gocon.jp/2024/sessions/2/
TIPS: օ͞Μ͕͙͢ʹ͑Δศརؔ slices.Chunk • sliceΛׂͯ͠ෳݸͷsliceΛฦ͢iter.Seq[[]E]Λ࡞Δ • Ͳ͏͍͏໘ʹศར͔ʁ => όϧΫͰॲཧ͍͕ͨ͠ɺҰؾʹΓ͗͢ Δͷྑ͘ͳ͍࣌
• SQLͰIN۟Λ༻͍ͨόϧΫऔಘ • Ұʹ͛ΒΕΔID͕nݸʹ੍ݶ͞Ε͍ͯΔόϧΫऔಘAPI
ඇಉظN+1Ϧκϧόʔͷເ
N+1 • ιγϟήͷྫ: users ςʔϒϧʹ user_weapons(උث) ςʔϒϧ͕ has-many Ͱ ͍͍ͭͯΔɻҰཡͰuserͱඋثΛηοτͰग़͍ͨ͠
• φΠʔϒͳ࣮: SELECT * FROM users WHERE … • ্هͰҾͬு͖ͬͯͨ݁ՌΛߦ͝ͱʹSELECT * FROM user_weapons WHERE user_id = ? • usersͷߦ͝ͱʹSQL͕ൃߦ͞Εͯ͠·͏ͨΊɺRDBMS·Ͱͷ௨৴Φʔόʔϔο υɺSQLύʔείετɺͳͲͳͲ͕ੵΈॏͳΓϨεϙϯελΠϜ͕ྼԽ͢Δ
GraphQLN+1͕ຊ࣭తʹى͜Γ͕ͪ • GraphQLͰɺ͋Δϊʔυʹඥͮ͘ࢠڙͷϊʔυΛऔΔΑ͏ͳΫΤϦΛΫϥΠ Ξϯτ͕ಈతʹΈཱͯͯൃߦ͢Δ͜ͱ͕Ͱ͖Δ • ී௨ʹφΠʔϒʹ࣮͢ΔͱN+1͕ൃੜ͢Δʂ • ͦ͜ͰGraphQLքͰdataloaderͱ͍͏ςΫ͕·͍ͬͯΔ • GoͷdataloaderͰɺϊʔυͷղܾΛඇಉظʹ͢Δ
+ छྨ͝ͱͷϊʔυͷղ ܾϦΫΤετΛόοϑΝϦϯάͯ͠όϧΫͰॲཧ͢Δ • dataloaderʹ͍ͬͯΕ΄ͱΜͲͷN+1͍͍ײ͡ʹղܾ͞ΕΔ
ҰํRESTfulͷN+1ղܾํ๏ • ϨεϙϯεͷΈཱͯํϑϨʔϜϫʔΫͰͳ͘ΞϓϦέʔγϣϯ ίʔυͷ • => dataloaderͷΑ͏ʹఆܕԽͰ͖ͳ͍ • ΄ͱΜͲͷέʔεͰεϥΠεΛฦ͢ͱ͖ʹಉظతʹεϥΠεͷதΛ ॱ൪ʹΈཱͯͯߦ͍ͬͯΔͷͰdataloaderͷద༻Ͱ͖ͳ͍
• => εϥΠεͷղܾΛඇಉظʹ͢Εྑ͍ͷͰʁ
github.com/mackee/iterutils/async.Map • go-functional/v2/it.Mapͷඇಉظ൛ • async.Map2͋ΔΑʂ • ͜ΕͰεϥΠεͷࢠͷϊʔυͷղܾΛdataloaderʹͤΔ͜ͱ͕Ͱ ͖ΔͷͰͳ͍͔
͍ํ
sync.WaitGroupͰࣄΓΔͷͰʁ • ҧ͍ͱͯ͠ɺॏͶ͕͚͕Մೳ • async.MapiterΛड͚ೖΕΔ ͭ·Γit.Mapasync.MapΛෳճ ֻ͚߹ΘͤΔ͜ͱ͕Ͱ͖Δ • ॲཧͷ࣮ߦࣗମɺslices.Collect ͞ΕΔ·ͰԆ͞ΕΔ
• ͪͳΈʹॱ൪ೖΕͨiter.Seqͷॱ൪ʹྻͯ͠ฦ͢Α͏ʹͳͬͯ ͍·͢
async.Map2ͷ͍ํ • errgroup.Groupʹ૬ • iter.Seq2[V, error] Λฦ͢ • it.TryCollectiter.Seq2[V, error]Λ৯ͯͲΕ͔ҰͭͰ
error͕͋Εଧͪͬͯ errorΛฦ͢
github.com/vikstrous/dataloadgen • GoͰdataloaderΛߦ͏ͭ • GenericsΛ͍ͬͯΔͷ Ͱੜ͠ͳͯ͘ศར(ର vektah/dataloaden)
࣮ࡍૣ͘ͳΔ͔ݕূͯ͠ΈΔ • ӈਤͷςʔϒϧΛ༻ҙ • fi xtureΛೖΕͨ users: 10000, items: 10000
user_items: 100000 • ϥϯμϜͰ500݅IDࢦఆͨ͠users ΛऔΓɺ͞Βʹ͍࣋ͬͯΔitemΛ ͱΔૢ࡞ • FkΠϯσοΫεష͍ͬͯͳ͍
N+1͕͋Δঢ়ଶͷίʔυ
Dataloaderʹͨ͠ͱ͖ͷಉ༷ͷίʔυ
Dataloaderʹͨ͠ͱ͖ͷಉ༷ͷίʔυ
ϕϯν݁Ռ 100ഒۙ͘ͷ͕͍ࠩͭͨ
ͦͷଞͷߟ • ࣮ISUCONͷաڈͰͬͯείΞ͕ͦΜͳʹ্͕Βͳ͍ • ਪଌ: CPU/ϝϞϦ੍͕ݶ͞Ε͍ͯͨΓ͢Δ͔Βʁ • ͔ͳΓgoroutineΛىಈ͢ΔͨΊʁ • ͔࣮͠͠ࡍͷݱͰgqlgen/dataloader͕ػೳ͍ͯ͠ΔҎ্ɺ͜ͷ
ख๏༗ޮͦ͏ͱݴ͑Δ • (͕͜͜λΠτϧͷʮເʯཁૉͰ͢)
·ͱΊ • GraphQLͰͳ͍໘ͰdataloaderΛ͏߹ʹɺasync.Map/ async.Map2͕༻Ͱ͖Δ͜ͱΛࣔͨ͠ • ͦͯ͋͠ΔఔޮՌతͰ͋Δ͜ͱ͕Θ͔ͬͨ • async.Map/dataloaderΛ͏ͱطଘͷσʔλΈཱͯͷߏ͔Β͋ ·Γม͑ͳͯ͘ྑ͍ͷͰϦϑΝΫλʹศར •
AΛݺͿͷʹBͷmap͕ඞཁΈ͍ͨͳґଘؔݮΒͤΔ
Ҏ্Ͱ͢ʂ • ͦͷଞ͓Βͤ: gitHub.com/mackee/iterutils ʹطଘͷΠςϨʔλͬ Ά͍interfaceΛiter.Seqʹม͢Δ͕ؔ͋ΔͷͰݟͯ͘Εʂ