Skip to content

Instantly share code, notes, and snippets.

@HParker
Created March 17, 2021 22:32
Show Gist options
  • Save HParker/b1000e559a0e11d8d84b0d226c485abf to your computer and use it in GitHub Desktop.
Save HParker/b1000e559a0e11d8d84b0d226c485abf to your computer and use it in GitHub Desktop.
Ruby dup optimization
⋊> ~/c/ruby on getlocal-of-same-object-becomes-dup ⨯ ./ruby --version 15:27:30
ruby 3.1.0dev (2021-03-17T21:17:37Z getlocal-of-same-o.. 383292776f) [x86_64-darwin19]
⋊> ~/c/ruby on getlocal-of-same-object-becomes-dup ⨯ /Users/hparker/.rbenv/shims/ruby --version 15:27:53
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
⋊> ~/c/ruby on getlocal-of-same-object-becomes-dup ⨯ benchmark-driver benchmark/repeated_local.rb -e ./ruby -e /Users/hparker/.rbenv/shims/ruby 15:27:55
Calculating -------------------------------------
./ruby /Users/hparker/.rbenv/shims/ruby
repeated_local 142.861k 166.678k i/s - 1.000 times in 0.000007s 0.000006s
Comparison:
repeated_local
/Users/hparker/.rbenv/shims/ruby: 166678.3 i/s
./ruby: 142860.8 i/s - 1.17x slower
⋊> ~/c/ruby on getlocal-of-same-object-becomes-dup ⨯ /Users/hparker/.rbenv/shims/ruby --dump=insns benchmark/repeated_local.rb 15:29:10
== disasm: #<ISeq:<main>@benchmark/repeated_local.rb:1 (1,0)-(6,15)> (catch: FALSE)
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0
0000 definemethod :square, square ( 1)[Li]
0003 putself ( 6)[Li]
0004 putobject 100
0006 opt_send_without_block <calldata!mid:square, argc:1, FCALL|ARGS_SIMPLE>
0008 dup
0009 setlocal_WC_0 x@0
0011 leave
== disasm: #<ISeq:square@benchmark/repeated_local.rb:1 (1,0)-(5,3)> (catch: FALSE)
== catch table
| catch type: break st: 0000 ed: 0004 sp: 0000 cont: 0004
| == disasm: #<ISeq:block in square@benchmark/repeated_local.rb:2 (2,10)-(4,5)> (catch: FALSE)
| == catch table
| | catch type: redo st: 0001 ed: 0007 sp: 0000 cont: 0001
| | catch type: next st: 0001 ed: 0007 sp: 0000 cont: 0007
| |------------------------------------------------------------------------
| 0000 nop ( 2)[Bc]
| 0001 getlocal_WC_1 x@0 ( 3)[Li]
| 0003 getlocal_WC_1 x@0
| 0005 opt_mult <calldata!mid:*, argc:1, ARGS_SIMPLE>
| 0007 nop
| 0008 leave ( 4)[Br]
|------------------------------------------------------------------------
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0<Arg>
0000 putobject_INT2FIX_1_ ( 2)[LiCa]
0001 send <calldata!mid:times, argc:0>, block in square
0004 nop
0005 leave ( 5)[Re]
⋊> ~/c/ruby on getlocal-of-same-object-becomes-dup ⨯ ./ruby --dump=insns benchmark/repeated_local.rb 15:29:17
== disasm: #<ISeq:<main>@benchmark/repeated_local.rb:1 (1,0)-(6,15)> (catch: FALSE)
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0
0000 definemethod :square, square ( 1)[Li]
0003 putself ( 6)[Li]
0004 putobject 100
0006 opt_send_without_block <calldata!mid:square, argc:1, FCALL|ARGS_SIMPLE>
0008 dup
0009 setlocal_WC_0 x@0
0011 leave
== disasm: #<ISeq:square@benchmark/repeated_local.rb:1 (1,0)-(5,3)> (catch: FALSE)
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0<Arg>
0000 putobject_INT2FIX_1_ ( 2)[LiCa]
0001 send <calldata!mid:times, argc:0>, block in square
0004 leave ( 5)[Re]
== disasm: #<ISeq:block in square@benchmark/repeated_local.rb:2 (2,10)-(4,5)> (catch: FALSE)
0000 getlocal_WC_1 x@0 ( 3)[LiBc]
0002 dup
0003 opt_mult <calldata!mid:*, argc:1, ARGS_SIMPLE>
0005 leave ( 4)[Br]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment