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
YARVの最適化について調べた
Search
na-o-ys
March 29, 2017
Programming
160
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
YARVの最適化について調べた
社内勉強会
na-o-ys
March 29, 2017
More Decks by na-o-ys
See All by na-o-ys
IoTと監視
naoys
1
830
RubyとJIT
naoys
0
180
将棋盤を画像認識したかった
naoys
0
1.6k
Rust で乗り換え案内
naoys
0
650
疎行列と Jaccard 類似度の高速計算
naoys
1
680
有理数集合の濃度
naoys
2
160
転職会議サービスのAWS移行記録
naoys
0
92
Anonymous Recursion in C++
naoys
0
440
入門AlphaGo
naoys
5
3.8k
Other Decks in Programming
See All in Programming
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
7.3k
Webフレームワークの ベンチマークについて
yusukebe
0
170
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.4k
OSもどきOS
arkw
0
580
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
410
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
250
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
120
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
130
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
170
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
550
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
200
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
How GitHub (no longer) Works
holman
316
150k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
260
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
360
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
260
Deep Space Network (abreviated)
tonyrice
0
210
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
BBQ
matthewcrist
89
10k
A better future with KSS
kneath
240
18k
Transcript
࠷దԽ YARV 2016/01/26 @na_o_ys
YARV ruby 1.8 Ҏલ ruby 1.9 Ҏ߱ VM όΠτίʔυ (ਤࢀߟ)
Rubyͷ͘͠Έ -Ruby Under a Microscope - Pat Shaughnessy
YARV ͍ • ϝϞϦޮ • ϫʔΩϯάϝϞϦ͕ີʹͳΓΩϟογϡϛε͕ݮগ • όΠτίʔυ࠷దԽςΫχοΫ • ໋ྩྻ͕γϦΞϧʹฒͿͷͰૢ࡞͕खܰ
• طଘݚڀͷݟ͕๛ (ࢀߟ) ·ͭͱ×ాɺRuby 1.9ΛޠΔ - ˏIT http://www.atmarkit.co.jp/news/200712/25/ruby.html
YARV ࠷దԽΦϓγϣϯ ※͜ΕҎ֎࠷దԽͨ͘͞Μ͍ͯ͠ΔͬΆ͍
YARV ࠷దԽΦϓγϣϯ • ˑ inline_const_cache • ˑ specialized_instruction • peephole_optimization
• operands_unification
ςΫχοΫͷུ֓ ιʔείʔυͷา͖ํ ࠓͷ༰
inline_const_cache
inline_const_cache ུ֓ (Πϝʔδ) module A::Module A_CONST = 'hello' end 10.times
do ... puts A::Module::A_CONST ... end module A::Module A_CONST = 'hello' end 10.times do ... puts 'hello' ... end -> ϧʔϓ1ճ ϧʔϓ2ճҎ߱ ఆ୳ࡧ(͍)͕ॳճͷΈͰࡁΉ
inline_const_cache όΠτίʔυ pry(main)> print RubyVM::InstructionSequence.compile("puts A_CONST").disasm == disasm: #<ISeq:<compiled>@<compiled>>================================ 0000
putself ( 1) 0001 getinlinecache 8, <is:0> 0004 getconstant :A_CONST 0006 setinlinecache <is:0> 0008 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0011 leave pry(main)> print RubyVM::InstructionSequence.compile("puts A_CONST").disasm == disasm: #<ISeq:<compiled>@<compiled>>================================ 0000 putself ( 1) 0001 putnil 0002 getconstant :A_CONST 0004 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0007 leave ద༻લ ద༻ޙ
inline_const_cache ιʔείʔυ pry(main)> print RubyVM::InstructionSequence.compile("puts A_CONST").disasm == disasm: #<ISeq:<compiled>@<compiled>>================================ 0000
putself ( 1) 0001 getinlinecache 8, <is:0> 0004 getconstant :A_CONST 0006 setinlinecache <is:0> 0008 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0011 leave • getinlinecache (8, <is:0>) • ΠϯϥΠϯΩϟογϡ <is:0> ʹ༗ޮͳ͕ηοτ͞Ε͍ͯΕ, ΛελοΫʹੵΈ, 8όΠτʹδϟϯϓ͢Δ • setinlinecache (<is:0>) • ΠϯϥΠϯΩϟογϡ <is:0> ʹελοΫτοϓͷΛηοτ͢Δ https://github.com/ruby/ruby/blob/trunk/insns.def#L1182
inline_const_cache Ωϟογϡফڈ • ruby ͷఆ࠶ఆٛՄೳ • దʹΩϟογϡফڈ͢Δඞཁ͕͋Δ • GLOBAL_CONSTANT_STATE •
VMͰҰҙͳ • ఆఆٛ/มߋͳͲͰ͕ΠϯΫϦϝϯτ • Ωϟογϡηοτ࣌ͷͱݱࡏͷ͕ҟͳΕ, ແޮΩϟογϡͱ Έͳ͞ΕΔ
inline_const_cache ·ͱΊ • ܁Γฦ͠෦Ͱͷఆ୳ࡧΛແ͘͢ • άϩʔόϧมΛͬͯΩϟογϡແޮԽ • insns.def ΛݟΕ YARV
໋ྩͷ࣮ମ͕Θ͔Δ
specialized_instruction
specialized_instruction ུ֓ (Πϝʔδ) puts 3 + 5 # 3.+(5) Fixnum#+
puts 3.2 - 5.1 # (3.2).-(5.1) Float#- puts opt_plus(3, 5) puts opt_minus(3.2, 5.1) -> • جຊతͳԋࢉΛ࠷దԽ (ಛघԽ) • + ԋࢉʹରͯ͠ݺΕΔ͜ͱ͕ଟ͍ • ϝιου୳ࡧίετΛݮ
specialized_instruction όΠτίʔυ pry(main)> print RubyVM::InstructionSequence.compile("puts 3+5").disasm == disasm: #<ISeq:<compiled>@<compiled>>================================ 0000
putself ( 1) 0001 putobject 3 0003 putobject 5 0005 send <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>, nil 0009 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>, nil 0013 leave pry(main)> print RubyVM::InstructionSequence.compile("puts 3+5").disasm == disasm: #<ISeq:<compiled>@<compiled>>================================ 0000 putself ( 1) 0001 putobject 3 0003 putobject 5 0005 opt_plus <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache> 0008 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0011 leave ద༻લ ద༻ޙ
specialized_instruction ιʔείʔυ (໋ྩ) if (recv と val は Fixnum?) {
if (Fixnum#+ は再定義されていない?) { return fix_plus(recv, val); } } else if (recv と val は Float?) { if (Float#+ は再定義されていない?) { return float_plus(recv, val); } } return send(:+, recv, val); (ུ֓) (ࢀߟ) YARV Maniacs ʲୈ 9 ճʳ ಛԽ໋ྩ http://magazine.rubyist.net/?0017-YarvManiacs https://github.com/ruby/ruby/blob/trunk/insns.def#L1309
specialized_instruction ιʔείʔυ (ίϯύΠϧ) • όΠτίʔυͷίϯύΠϧ࣌ʹಛघԽ໋ྩʹஔ͖͍͑ͯΔ • + - * /
% == != < >, … https://github.com/ruby/ruby/blob/trunk/compile.c#L2279 case idPLUS: SP_INSN(plus); return COMPILE_OK; case idMINUS: SP_INSN(minus); return COMPILE_OK; case idMULT: SP_INSN(mult); return COMPILE_OK; case idDIV: SP_INSN(div); return COMPILE_OK; case idMOD: SP_INSN(mod); return COMPILE_OK; case idEq: SP_INSN(eq); return COMPILE_OK; case idNeq: SP_INSN(neq); return COMPILE_OK; case idLT: SP_INSN(lt); return COMPILE_OK; case idLE: SP_INSN(le); return COMPILE_OK; case idGT: SP_INSN(gt); return COMPILE_OK; case idGE: SP_INSN(ge); return COMPILE_OK; case idLTLT: SP_INSN(ltlt); return COMPILE_OK; case idAREF: SP_INSN(aref); return COMPILE_OK;
specialized_instruction ϝιου࠶ఆٛ • ࠷దԽରͷΫϥε/ϝιουʹ͍ͭͯ, ࠶ఆٛͷ༗ແΛ ϑϥάͰཧ͍ͯ͠Δ˞ • Fixnum, Float, String,
Array, Hash, BigNum, Symbol, Time, Regex, Nil, True, False • ϓϦϛςΟϒͳΫϥεʹର͢Δϝιου࠶ఆٛ, ύϑΥʔϚϯεμϯͷݪҼʹͳΔ ※ https://github.com/ruby/ruby/blob/trunk/vm_core.h#L565
specialized_instruction ·ͱΊ • جຊԋࢉͰͷϝιου୳ࡧΛແ͘͢ • ϝιουݺͼग़͠ (send) Λ, ಛघԽ͞Εͨ YARV
໋ྩʹஔ͖͑Δ͜ͱͰ࣮ݱ • ໋ྩͷ࣮ମ: insns.def ஔ: compile.c
peephole_optimization ͱ operands_unification
peephole_optimization jump LABEL1 ... LABEL1: jump LABEL2 jump LABEL2 ...
-> ద༻લ ద༻ޙ • όΠτίʔυྻʹର͢Δෳͷ࠷దԽͷ૯শ • ෆཁͳδϟϯϓΛআͨ͠Γ
operands_unification • සൟʹΘΕΔ YARV ໋ྩͷΦϖϥϯυΛಛघԽ pry(main)> print RubyVM::InstructionSequence.compile("puts 1").disasm ==
disasm: #<ISeq:<compiled>@<compiled>>================================ 0000 putself ( 1) 0001 putobject 1 0003 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0006 leave pry(main)> print RubyVM::InstructionSequence.compile("puts 1").disasm == disasm: #<ISeq:<compiled>@<compiled>>================================ 0000 putself ( 1) 0001 putobject_OP_INT2FIX_O_1_C_ 0002 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache> 0005 leave ద༻લ ద༻ޙ
࠷దԽ YARV ·ͱΊ • όΠτίʔυԽͷԸܙ • ෳͷ࠷దԽख๏ • ࠓհͨ͠Ҏ֎ʹ •
ϝιουσΟεύονͰͷΩϟογϡ • ͜Ε͔ΒͷτϐοΫ • AOT/JIT • ʹඋ͑ͯ YARV ͷಈ͖͓͖͍͑ͯͨ