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
もうちょっといいRubyプロファイラを作りたい (2025)
Search
osyoyu
August 30, 2025
Programming
860
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
もうちょっといいRubyプロファイラを作りたい (2025)
osyoyu
August 30, 2025
More Decks by osyoyu
See All by osyoyu
Wi-Fiはどこから来たのか Wi-Fiは何者か Wi-Fiはどこへ行くのか
osyoyu
0
580
Profile and benchmark every change - RubyKaigi 2025
osyoyu
0
170
Regional.rb and the Tokyo Metropolis
osyoyu
0
280
都市伝説バスターズ「WebアプリのボトルネックはDBだから言語の性能は関係ない」 - Kaigi on Rails 2024
osyoyu
29
19k
プロファイラ開発者と見る「推測するな、計測せよ」 - YAPC::Hakodate 2024
osyoyu
7
1k
ZigでC拡張を作る 2024 Edition
osyoyu
1
150
Rubyのパフォーマンスプロファイリングの改善 / Enhancing performance profiling for Ruby
osyoyu
2
1.2k
RubyKaigi Decks
osyoyu
0
250
The depths of profiling Ruby - RubyKaigi 2024
osyoyu
3
8.3k
Other Decks in Programming
See All in Programming
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
170
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
580
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
110
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
霧の中の代数的エフェクト
funnyycat
1
390
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
390
初めてのKubernetes 本番運用でハマった話
oku053
0
130
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
520
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
940
1B+ /day規模のログを管理する技術
broadleaf
0
140
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
150
5分で問診!Composer セキュリティ健康診断
codmoninc
0
280
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Amusing Abliteration
ianozsvald
1
230
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
650
Java REST API Framework Comparison - PWX 2021
mraible
34
9.5k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.4k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
470
The agentic SEO stack - context over prompts
schlessera
0
850
Ethics towards AI in product and experience design
skipperchong
2
330
RailsConf 2023
tenderlove
30
1.5k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Transcript
osyoyu | RubyKaigi 2025 follow up ͏ͪΐͬͱ͍͍ RubyϓϩϑΝΠϥΛ࡞Γ͍ͨ (2025)
pp @osyoyu • Daisuke Aritomo / ༗༑ େี • https://github.com/osyoyu
ຊͷݩωλ Profile and benchmark every change (RubyKaigi 2025) The depths
of profiling Ruby (RubyKaigi 2024)
ͻ͖͖ͭͮRubyϓϩϑΝΠϥ࡞ͬͯ·͢ • ϓϩϑΝΠϥ • ϓϩάϥϜͷ͍ՕॴΛൃݟ͢Δπʔϧ
github.com/osyoyu/pf2 • Rubyͷ "۱ʑ·Ͱ" "ਖ਼֬ʹ" ଌఆ Ͱ͖Δ͜ͱΛࢦ͢ • RubyϑϨʔϜ •
C (Native) ϑϨʔϜ • GVLͷ༗ঢ়گ • Sampling, In-process ͳϓϩϑΝΠϥ ͱͯ͠ઃܭ • ͙͢ΕͨϏδϡΞϥΠζͦͳ͑Δ 2024ͷεϥΠυ
ϏδϡΞϥΠζ εϨου͝ͱͷ༷ࢠͷ τϥοΫ ίʔϧπϦʔ Flamegraph 2024ͷεϥΠυ
Optcarrot with C frames 2024ͷεϥΠυ
࠷ۙͷΈ
None
None
ϓϩϑΝΠϥͷಈͬͯԿʁ
Έᶃ ϝϞϦΛେྔʹফඅ͢Δ ϝϞϦ͕ͨ͘͞Μ͋ΕͲ͏ͱ͍͏͜ͱͳ͍ • 20 MB/s ͙Β͍ͰϝϞϦ͕৯͍ͭͿ͞Ε͍ͯ͘ • •
ಉؔ͡ͷใΛෳճه͠ͳ͍Α͏ʹͨ͠Γ • ಉ͡ελοΫͷใΛෳճه͠ͳ͍Α͏ʹͨ͠Γ • ͪΌΜͱςʔϒϧΛ࡞Δͱී௨ʹղܾ͢Δ • ࣮ͰϥΫΛ͍͚ͯ͠ͳ͍ • ϝϞϦ͕͋;Εͦ͏ʹͳͬͨΒϑΝΠϧʹॻ͖ग़͢ػೳΛ࣮ͯ͠ΈͨΓ
Έᶄ ϓϩϑΝΠϧͯ͠ΔͱσουϩοΫ͢Δ ͪ͜Β࠷ѱ • ͳΜ͔ϋϯά͢Δ • ʮ৽͍͠εϨου͕ੜ·Εͨͱ͖ʹϓϩϑΝΠϧରʹՃ͢ΔʯػೳΛ ༗ޮʹ͢ΔͱɺϥϯμϜʹԿ͔͕σουϩοΫ͢Δ • ࠷ѱ
• ^Z kill -9 %1 ͷೖྗ͕͔ͳΓ͘ͳͬͨ
ෆ҆ఆͳ࣮ΖΖ • ͍Ζ͍Ζͳ߹Ͱ rb_thread_t ͷߏΛίϐϖ ͍ͯ࣋ͬͯ͠Δ • rb_thread_t ͷߏ͕มΘΔͱવյΕΔ •
͍Ζ͍ΖฒྻʹΔͷͰɺΑ͔ͬͯ͘ͳ͍ ··ࡶʹ Mutex ΛೖΕ·ͬͯͨ͘ • વͷใ͍Λड͚Δ #[repr(C)] struct rb_native_thread { _padding_serial: [c_char; 4], // rb_atomic_t _padding_vm: *mut c_int, // struct rb_vm_struct thread_id: rb_nativethread_id_t, // ... } #[repr(C)] struct rb_thread_struct { _padding_lt_node: [c_char; 16], // struct ccan_list_node _padding_self: VALUE, _padding_ractor: *mut c_int, // rb_ractor_t _padding_vm: *mut c_int, // rb_vm_t nt: *mut rb_native_thread, // ...
ϦϥΠτ & ͍ͭͰʹRust͔ΒC • 2ճʢ3ճʁʣͷ࣮ͳͷͰɺલΑΓ໌Β͔ʹચ࿅͞Εͨ • MutexΛ΄ͱΜͲΊͯɺඞཁͳͱ͜Ζ͚ͩϩοΫϑϦʔͳߏʹ • ͋ͱVec૬Λ͏ͷΛΊΒΕͨΓ •
ଟ͍ϦϯάόοϑΝΛॻ͚ͨΓ • ଞʹຯʹ͏Ε͍͜͠ͱ͕ • ruby.h Ͱఏڙ͞ΕΔϚΫϩ͕͑Δʂ • ͕ϥΫʂ • ίϯύΠϧ࣌ʹݕͰ͖Δϛεݮ͚ͬͨͲɺͲ͏ͤ΄΅શ෦unsafeͩͬͨ͠
Έᶅ ͍͍ϓϩϑΝΠϧର͕खݩʹͳ͍ MandelbrotͱRailsΛϓϩϑΝΠϧ͢Δͷ͖ͨ
Έᶅ ͍͍ϓϩϑΝΠϧର͕खݩʹͳ͍ MandelbrotͱRailsΛϓϩϑΝΠϧ͢Δͷ͖ͨ • ࠓ͓͠Ζͦ͏ͳλʔήοτͷΛ2ͭฉ͚ͨͷͰղܾ͠·ͨ͠
Έᶆ ΘΕͯͳ͍ ͦ͏ͩͶ • લड़ͷΑ͏ʹɺ҆ఆͯ͠ͳ͍ػೳ͕ଟ͍͠…… • ͪΌΜͱએͯ͠ͳ͍͠……
ͦΜͳ͜ΜͳͰɺͦΖͦΖ৽όʔδϣϯΛग़͍ͨ͠ • શ໘ϦϥΠτͨ͜͠ͱͰ͔ͳΓ҆ఆͨ͠ͷͰɺϦϦʔε͍ͨ͠Ͱ͢Ͷ • master ʹ͔͠ͳ͍मਖ਼͕େྔʹ͋Δ
None
None
࠷ۙͷ Brendan Greggઌੜʹձͬͨ • ύϑΥʔϚϯεੳͷେՈ • Flame GraphΛൃ໌ͨ͠ਓ • ଞʹେྔͷख๏Λ։ൃ͍ͯ͠Δ
• ϓϩϑΝΠϥʹ͍ͭͯ ͍ΖΜͳΞυόΠεΛΒͬͨ
Brendan Gregg ઌੜͷݴ༿ • Կى͍ͬͯ͜ͳͯ͘ɺ1ʹ1ɺ1ఔͷϓϩϑΝΠϧΛ औ͓ͬͯ͘ͱ͍͍ • Կ͔͕ى͖ͨͱ͖ɺ͍͔ͭΒى͖͔ͨͷௐࠪʹ༗༻ • ͳΔ΄Ͳʙ
• ͲͪΒ͔ͱ͍͏ͱAPM͕ఏڙ͢Δػೳͳؾ͕͢Δ͕ • ࡶʹͦΕΛΕΔπʔϧ͕͍͍͔͋ͬͯ
ʮKernelͷϑϨʔϜݟ͑ͨ΄͏͕͍͍ʯ • Pf2RubyϑϨʔϜͱCϑϨʔϜΛ ߹ͯ͠දࣔ͢Δ͜ͱ͕Ͱ͖Δ • ͦ͜ʹKernelͷϑϨʔϜ (syscallͷઌ) ग़ͨ΄͏͕͍͍Αɺͱ͍͏ • ͪΐͬͱ͏Ε͕͠͞·͔ͩͬͯͳ͍
• eBPFΛΘͳ͍ͱऔΕͳͦ͞͏Ͱ ·ͩख͕ಈ͍ͯͳ͍ 2024ͷεϥΠυ
Flame Scope ࠷ۙͷൃ໌ ࣮ͨ͠ʂ
None
Δ͔ʙ……
ϓϩϑΝΠϥྖҬͰ͋Γͦ͏ͳ՝ཧ • ෛՙͳ wall-time profiling • ຊདྷ I/O Λ࢝ΊͨॠؒͱऴΘͬͨॠ͚ؒͩهͯ͠ɺ ޙ͔Βܭࢉ͢Ε͍͍͕ɺࠓͷ
Ruby ϓϩϑΝΠϥͷଟ͘ "શεϨουʹఆظతʹࠓͬͯΔ͜ͱΛ͍߹Θͤ" ͍ͯ͠Δ • JIT͞Ε͔ͨؔͲ͏͔Γ͍ͨ • YJITYJITͰ perf map Λग़ྗͰ͖Δ͕ɺະJITϝιουݟ͑ͳ͍
ϓϩϑΝΠϥྖҬͰ͋Γͦ͏ͳ՝ཧ • LLM-readable flamegraph • ը૾ͱͯ͠VLMʹಡ·ͤͯ ԿಡΈऔΕ͍ͯͳ͍
ϓϩϑΝΠϥྖҬͰ͋Γͦ͏ͳ՝ཧ • perf, eBPF ରԠ • ී௨ʹ perf ͰϓϩϑΝΠϥऔͬͨͱ͖ʹRubyϑϨʔϜݟ͍ͨ •
͑ʙʙ ຊʹʁʁʁ • Linux Ҏ֎Ͳ͏͢Μͷʁ • ͓ͩͬͯલΒ Mac Ͱ։ൃͯ͠ͳ͍ʁ • WSL Docker (Mac) Ͱ·ͱʹperf͑ͳ͍͚ͲେৎͰ͔͢ʁ • ͳͷͰ͋Μ·Γڵຯͳ͍
େRactor࣌
େ՝ɿRactor ରԠ • rb_profile_frames() શવ Ractor ͷ͜ͱΛڭ͑ͯ͘Εͳ͍ • ϓϩηε֎Ͱͬͯ ruby
ϓϩηεͷϝϞϦΛղऍ͢ΔλΠϓͷ ϓϩϑΝΠϥͰ Ractor ͷ͜ͱΛΔͷ͔ͳΓେมͦ͏ • M:N ʹͳΔͷ͕͔ͳΓΩπ͍
GoOpenJDK͔ΒֶͿ • ॲཧܥʹΑͬͯͱΕΔϓϩϑΝΠϧखஈେ͖͘ҟͳͬͯ͘Δ • ϥϯλΠϜͷͳ͍ݴޠͰϓϩϑΝΠϥΛ֎෦ʹஔ͔͟ΔΛಘͳ͍ • ҰํɺΘΓͱෳࡶͳϥϯλΠϜΛ͍ͬͯΔݴޠ ϓϩϑΝΠϥΛ෦ʹ͕࣋ͪͪ • Go:
runtime/pprof ɺJava: JFR, AsyncGetCallTrace() • ಛʹGoGoroutineͷΈ͕Ractorʹ͍ۙͷͰ ϓϩϑΝΠϥͷߏࢀߟʹͳΔͩΖ͏
CRuby ͷதʹϓϩϑΝΠϥΛೖΕͯ͠·͏͔? ext/profiler ৽ઃ • ݁ہͷͱ͜ΖɺϓϩϑΝΠϥ࣮ߦঢ়ଶΛΩϟϓνϟ͢Δͷ • ϥϯλΠϜ͕͋ΔͳΒɺϥϯλΠϜʹͦͷػೳ͕͋Δͷ͕߹ཧత? • ֎෦ϓϩηεʹ͢Δ͔Βෆ҆ఆͳ
struct ίϐϖ͕ඞཁʹͳΔ • ext/profiler ͱ͔ʹೖΕͯ͠·͏ͷ͕͍͍ͷ͔ͳʔ • ࢼ࡞ͯ͠Έͨͱ͜ΖɺGET_VM() rb_thread_t ͑ͯศར
ࢼ࡞த: Ractor / M:N ରԠ in ext/profiler • Ractor Ҏલʮ1ϓϩηεͰಉ࣌ʹCPUΛ͑Δͷ
1εϨου͚ͩʯͱ͍͏ԾఆΛ͓͚ͨ ※ GVLΛख์͢C֦ு͜͜Ͱແࢹ • Ractor ͰͦͷԾఆ่͕ΕΔ • Χʔωϧ͔Βʮϓϩηε͕CPU timeΛ10 msͬͨʯ௨Λ ड͚औͬͨͱ͖ɺͦΕ͕ͲͷΧʔωϧεϨουɾRuby ThreadʹΑΔͷ͔ ࣝผͰ͖ͳ͍ͱ͍͚ͳ͍ େ Ractor ࣌
ࢼ࡞த: Ractor / M:N ରԠ in ext/profiler • Linux Ͱ
timer_create(CLOCK_THREAD_CPUTIME_ID) Λ͏͜ͱͰ ΧʔωϧεϨου୯ҐͰফඅͨ͠CPU࣌ؒΛτϥοΩϯάͰ͖Δ • ͔͠͠ΧʔωϧεϨουͱRuby ThreadͷରԠC APIͰެ։͞Ε͍ͯͳ͍ Kernel Thread 1 Ruby Thread KT 2 RT RT RT KT 2 ͕͋ΔॠؒʹͲͷ RT Λ࣮ߦ͍͔ͯͨ͠ ϓϩϑΝΠϥͱͯ͠Γ͍ͨ
͜Μͳײ͡ʹͳΓͦ͏? • Native Thread ͝ͱʹΧʔωϧλΠϚʔΛઃఆ͢Δ • ϓϩϑΝΠϥ͕ىಈͨ͠ͱ͖ͱɺͦͷޙεϨου͕৽نʹىಈͨ͠ͱ͖ʹ ઃఆ • thread_sched_switch
Ͱ Ractor ؒͷεϨουͷҠಈΛه͢Δ • ͱࢥ͚ͬͨͲɺγάφϧϋϯυϥͰ GET_RACTOR() ͍͍ͯ͠ͳΒ ͦΕͰ͍͍
ͱ͍͏Θ͚Ͱ • ແͳվળΛਐΊ͍ͯ·͢ • ͦΕͦ͏ͱ Ruby 3.5 ʹ͚ͯɺCRuby ʹϓϩϑΝΠϥΛઃஔ͢Δ Ξϓϩʔν͕ݱ࣮త͔͔֬ΊΑ͏ͱ͍ͯ͠·͢