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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
osyoyu
August 30, 2025
Programming
840
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
440
Profile and benchmark every change - RubyKaigi 2025
osyoyu
0
160
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
140
Rubyのパフォーマンスプロファイリングの改善 / Enhancing performance profiling for Ruby
osyoyu
2
1.1k
RubyKaigi Decks
osyoyu
0
240
The depths of profiling Ruby - RubyKaigi 2024
osyoyu
3
8.2k
Other Decks in Programming
See All in Programming
Lessons from Spec-Driven Development
simas
PRO
0
140
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
120
New "Type" system on PicoRuby
pocke
1
490
AutonomyとControlのあいだ:Graflowで記述するAIエージェント協調
myui
0
110
Oxcを導入して開発体験が向上した話
yug1224
4
290
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.5k
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
260
Why Laravel apps break—Mastering the fundamentals to keep them maintainable
kentaroutakeda
1
340
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
500
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
580
Featured
See All Featured
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
220
Color Theory Basics | Prateek | Gurzu
gurzu
0
360
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
190
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
460
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.8k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
The agentic SEO stack - context over prompts
schlessera
0
800
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
1.6k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
KATA
mclloyd
PRO
35
15k
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 ʹϓϩϑΝΠϥΛઃஔ͢Δ Ξϓϩʔν͕ݱ࣮త͔͔֬ΊΑ͏ͱ͍ͯ͠·͢