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 6 years ago
- Tracker changed from Misc to Feature
Updated by nobu (Nobuyoshi Nakada) over 6 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 6 years ago
Could you give us your idea with examples in pseudo-code?
Updated by chopraanmol1 (Anmol Chopra) over 6 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