Feature #14984
closedcase when with splat operator performance
Description
case when with splat operator use instructions like duparray, concatarray which result in creation of arrays.
Avoiding creation of array improves performance.
I've done following set of changes:
https://github.com/ruby/ruby/pull/1928
Which resulted into following benchmark result
Current trunk
4.648000 0.000000 4.648000 ( 4.644334)
Modified
1.900000 0.000000 1.900000 ( 1.906208)
Changes in InstructionSequence are as follow
Current trunk
disasm: #<ISeq:case_splat@../bench_when_splat.rb:17 (17,0)-(40,3)> (catch: FALSE) local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] i@0<Arg> 0000 getlocal_WC_0 i@0 ( 18)[LiCa] 0002 dup ( 19) 0003 getinlinecache 10, <is:0> 0006 getconstant :C0_9 0008 setinlinecache <is:0> 0010 splatarray true 0012 checkmatch 6 0014 branchif 192 0016 dup ( 21) 0017 getinlinecache 24, <is:1> 0020 getconstant :C10_18 0022 setinlinecache <is:1> 0024 splatarray true 0026 putobject 19 0028 newarray 1 0030 concatarray 0031 checkmatch 6 0033 branchif 196 0035 dup ( 23) 0036 duparray [29] 0038 getinlinecache 45, <is:2> 0041 getconstant :C20_28 0043 setinlinecache <is:2> 0045 concatarray 0046 checkmatch 6 0048 branchif 200 0050 dup ( 25) 0051 getinlinecache 58, <is:3> 0054 getconstant :C30_37 0056 setinlinecache <is:3> 0058 splatarray true 0060 duparray [38, 39] 0062 concatarray 0063 checkmatch 6 0065 branchif 204 0067 dup ( 27) 0068 duparray [48, 49] 0070 getinlinecache 77, <is:4> 0073 getconstant :C40_47 0075 setinlinecache <is:4> 0077 concatarray 0078 checkmatch 6 0080 branchif 208 0082 dup ( 29) 0083 getinlinecache 90, <is:5> 0086 getconstant :C50_56 0088 setinlinecache <is:5> 0090 splatarray true 0092 duparray [57, 58] 0094 concatarray 0095 putobject 59 0097 newarray 1 0099 concatarray 0100 checkmatch 6 0102 branchif 212 0104 dup ( 31) 0105 duparray [67, 68, 69] 0107 getinlinecache 114, <is:6> 0110 getconstant :C60_66 0112 setinlinecache <is:6> 0114 concatarray 0115 checkmatch 6 0117 branchif 216 0119 dup ( 33) 0120 getinlinecache 127, <is:7> 0123 getconstant :C70_74 0125 setinlinecache <is:7> 0127 splatarray true 0129 getinlinecache 136, <is:8> 0132 getconstant :C75_79 0134 setinlinecache <is:8> 0136 concatarray 0137 checkmatch 6 0139 branchif 220 0141 dup ( 35) 0142 getinlinecache 149, <is:9> 0145 getconstant :C80_83 0147 setinlinecache <is:9> 0149 splatarray true 0151 getinlinecache 158, <is:10> 0154 getconstant :C84_87 0156 setinlinecache <is:10> 0158 concatarray 0159 duparray [88, 89] 0161 concatarray 0162 checkmatch 6 0164 branchif 224 0166 dup ( 37) 0167 duparray [98, 99] 0169 getinlinecache 176, <is:11> 0172 getconstant :C90_93 0174 setinlinecache <is:11> 0176 concatarray 0177 getinlinecache 184, <is:12> 0180 getconstant :C94_97 0182 setinlinecache <is:12> 0184 concatarray 0185 checkmatch 6 0187 branchif 228 0189 pop ( 18) 0190 putnil 0191 leave ( 40)[Re] 0192 pop ( 19) 0193 putobject 0..9 ( 20)[Li] 0195 leave ( 40)[Re] 0196 pop ( 21) 0197 putobject 10..19 ( 22)[Li] 0199 leave ( 40)[Re] 0200 pop ( 23) 0201 putobject 20..29 ( 24)[Li] 0203 leave ( 40)[Re] 0204 pop ( 25) 0205 putobject 30..39 ( 26)[Li] 0207 leave ( 40)[Re] 0208 pop ( 27) 0209 putobject 40..49 ( 28)[Li] 0211 leave ( 40)[Re] 0212 pop ( 29) 0213 putobject 50..59 ( 30)[Li] 0215 leave ( 40)[Re] 0216 pop ( 31) 0217 putobject 60..69 ( 32)[Li] 0219 leave ( 40)[Re] 0220 pop ( 33) 0221 putobject 70..79 ( 34)[Li] 0223 leave ( 40)[Re] 0224 pop ( 35) 0225 putobject 80..89 ( 36)[Li] 0227 leave ( 40)[Re] 0228 pop ( 37) 0229 putobject 90..99 ( 38)[Li] 0231 leave ( 40)[Re]
Modified
disasm: #<ISeq:case_splat@../bench_when_splat.rb:17 (17,0)-(40,3)> (catch: FALSE) local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] i@0<Arg> 0000 getlocal_WC_0 i@0 ( 18)[LiCa] 0002 dup ( 19) 0003 getinlinecache 10, <is:0> 0006 getconstant :C0_9 0008 setinlinecache <is:0> 0010 splatarray false 0012 checkmatch 6 0014 branchif 299 0016 dup ( 21) 0017 getinlinecache 24, <is:1> 0020 getconstant :C10_18 0022 setinlinecache <is:1> 0024 splatarray false 0026 checkmatch 6 0028 branchif 303 0030 dup 0031 putobject 19 0033 checkmatch 2 0035 branchif 303 0037 dup ( 23) 0038 putobject 29 0040 checkmatch 2 0042 branchif 307 0044 dup 0045 getinlinecache 52, <is:2> 0048 getconstant :C20_28 0050 setinlinecache <is:2> 0052 splatarray false 0054 checkmatch 6 0056 branchif 307 0058 dup ( 25) 0059 getinlinecache 66, <is:3> 0062 getconstant :C30_37 0064 setinlinecache <is:3> 0066 splatarray false 0068 checkmatch 6 0070 branchif 311 0072 dup 0073 putobject 38 0075 checkmatch 2 0077 branchif 311 0079 dup 0080 putobject 39 0082 checkmatch 2 0084 branchif 311 0086 dup ( 27) 0087 putobject 48 0089 checkmatch 2 0091 branchif 315 0093 dup 0094 putobject 49 0096 checkmatch 2 0098 branchif 315 0100 dup 0101 getinlinecache 108, <is:4> 0104 getconstant :C40_47 0106 setinlinecache <is:4> 0108 splatarray false 0110 checkmatch 6 0112 branchif 315 0114 dup ( 29) 0115 getinlinecache 122, <is:5> 0118 getconstant :C50_56 0120 setinlinecache <is:5> 0122 splatarray false 0124 checkmatch 6 0126 branchif 319 0128 dup 0129 putobject 57 0131 checkmatch 2 0133 branchif 319 0135 dup 0136 putobject 58 0138 checkmatch 2 0140 branchif 319 0142 dup 0143 putobject 59 0145 checkmatch 2 0147 branchif 319 0149 dup ( 31) 0150 putobject 67 0152 checkmatch 2 0154 branchif 323 0156 dup 0157 putobject 68 0159 checkmatch 2 0161 branchif 323 0163 dup 0164 putobject 69 0166 checkmatch 2 0168 branchif 323 0170 dup 0171 getinlinecache 178, <is:6> 0174 getconstant :C60_66 0176 setinlinecache <is:6> 0178 splatarray false 0180 checkmatch 6 0182 branchif 323 0184 dup ( 33) 0185 getinlinecache 192, <is:7> 0188 getconstant :C70_74 0190 setinlinecache <is:7> 0192 splatarray false 0194 checkmatch 6 0196 branchif 327 0198 dup 0199 getinlinecache 206, <is:8> 0202 getconstant :C75_79 0204 setinlinecache <is:8> 0206 splatarray false 0208 checkmatch 6 0210 branchif 327 0212 dup ( 35) 0213 getinlinecache 220, <is:9> 0216 getconstant :C80_83 0218 setinlinecache <is:9> 0220 splatarray false 0222 checkmatch 6 0224 branchif 331 0226 dup 0227 getinlinecache 234, <is:10> 0230 getconstant :C84_87 0232 setinlinecache <is:10> 0234 splatarray false 0236 checkmatch 6 0238 branchif 331 0240 dup 0241 putobject 88 0243 checkmatch 2 0245 branchif 331 0247 dup 0248 putobject 89 0250 checkmatch 2 0252 branchif 331 0254 dup ( 37) 0255 putobject 98 0257 checkmatch 2 0259 branchif 335 0261 dup 0262 putobject 99 0264 checkmatch 2 0266 branchif 335 0268 dup 0269 getinlinecache 276, <is:11> 0272 getconstant :C90_93 0274 setinlinecache <is:11> 0276 splatarray false 0278 checkmatch 6 0280 branchif 335 0282 dup 0283 getinlinecache 290, <is:12> 0286 getconstant :C94_97 0288 setinlinecache <is:12> 0290 splatarray false 0292 checkmatch 6 0294 branchif 335 0296 pop ( 18) 0297 putnil 0298 leave ( 40)[Re] 0299 pop ( 19) 0300 putobject 0..9 ( 20)[Li] 0302 leave ( 40)[Re] 0303 pop ( 21) 0304 putobject 10..19 ( 22)[Li] 0306 leave ( 40)[Re] 0307 pop ( 23) 0308 putobject 20..29 ( 24)[Li] 0310 leave ( 40)[Re] 0311 pop ( 25) 0312 putobject 30..39 ( 26)[Li] 0314 leave ( 40)[Re] 0315 pop ( 27) 0316 putobject 40..49 ( 28)[Li] 0318 leave ( 40)[Re] 0319 pop ( 29) 0320 putobject 50..59 ( 30)[Li] 0322 leave ( 40)[Re] 0323 pop ( 31) 0324 putobject 60..69 ( 32)[Li] 0326 leave ( 40)[Re] 0327 pop ( 33) 0328 putobject 70..79 ( 34)[Li] 0330 leave ( 40)[Re] 0331 pop ( 35) 0332 putobject 80..89 ( 36)[Li] 0334 leave ( 40)[Re] 0335 pop ( 37) 0336 putobject 90..99 ( 38)[Li] 0338 leave ( 40)[Re]
Files
Updated by nobu (Nobuyoshi Nakada) over 2 years ago
- Tracker changed from Misc to Feature
Updated by nobu (Nobuyoshi Nakada) over 2 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r64318.
Optimization for case when with splat operator
[Fix GH-1928] [Feature #14984]
From: chopraanmol1 chopraanmol1@gmail.com
Updated by ko1 (Koichi Sasada) over 2 years ago
Could you give us your idea with examples in pseudo-code?
Updated by chopraanmol1 (Anmol Chopra) over 2 years ago
ko1 (Koichi Sasada) wrote:
Could you give us your idea with examples in pseudo-code?
I'm not sure if I understand your question. In case if you are asking about implementation for this issue, then I created a pull request for that:
https://github.com/ruby/ruby/pull/1928
Which Nobu applied in the following commit:
https://github.com/ruby/ruby/commit/af2e98ae801695155f98288836d814e373be769a