Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
もうちょっといいRubyプロファイラを作りたい (2025)
Search
osyoyu
August 30, 2025
Programming
920
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
680
Profile and benchmark every change - RubyKaigi 2025
osyoyu
0
200
Regional.rb and the Tokyo Metropolis
osyoyu
0
300
都市伝説バスターズ「WebアプリのボトルネックはDBだから言語の性能は関係ない」 - Kaigi on Rails 2024
osyoyu
29
20k
プロファイラ開発者と見る「推測するな、計測せよ」 - YAPC::Hakodate 2024
osyoyu
7
1.1k
ZigでC拡張を作る 2024 Edition
osyoyu
1
170
Rubyのパフォーマンスプロファイリングの改善 / Enhancing performance profiling for Ruby
osyoyu
2
1.2k
RubyKaigi Decks
osyoyu
0
260
The depths of profiling Ruby - RubyKaigi 2024
osyoyu
3
8.7k
Other Decks in Programming
See All in Programming
Workers Cache を知る
syumai
0
370
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.7k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
230
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
170
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
0
120
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
Kotlinの15年とServer-Side Kotlin
n_takehata
1
160
sbt 2.0: takeoff
eed3si9n
0
160
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
Verilogで学ぶCPU自作入門
uyuki234
8
4.1k
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
180
Railsバージョンを4倍にした話
optim
0
460
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
500
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.8k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.4k
4 Signs Your Business is Dying
shpigford
187
23k
Designing for Performance
lara
612
70k
Product Roadmaps are Hard
iamctodd
55
13k
Test your architecture with Archunit
thirion
2
2.4k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
560
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
830
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
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 ʹϓϩϑΝΠϥΛઃஔ͢Δ Ξϓϩʔν͕ݱ࣮త͔͔֬ΊΑ͏ͱ͍ͯ͠·͢