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
190
将棋盤を画像認識したかった
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
450
入門AlphaGo
naoys
5
3.8k
Other Decks in Programming
See All in Programming
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
310
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
150
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.1k
自作OSでスライド発表する
uyuki234
1
3.9k
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
310
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
4
1.4k
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.7k
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
200
継続モナドとリアクティブプログラミング
yukikurage
3
620
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
360
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
150
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Discover your Explorer Soul
emna__ayadi
2
1.2k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
The browser strikes back
jonoalderson
0
1.4k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
500
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
260
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Done Done
chrislema
186
16k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
1k
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 ͷಈ͖͓͖͍͑ͯͨ