Project

General

Profile

Actions

Feature #14984

closed

case when with splat operator performance

Added by chopraanmol1 (Anmol Chopra) over 5 years ago. Updated over 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:88451]

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

bench_when_splat.rb (964 Bytes) bench_when_splat.rb O/P:Benchmark + InstructionSequence chopraanmol1 (Anmol Chopra), 08/11/2018 06:41 PM
Actions #1

Updated by nobu (Nobuyoshi Nakada) over 5 years ago

  • Tracker changed from Misc to Feature
Actions #2

Updated by nobu (Nobuyoshi Nakada) over 5 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

Updated by ko1 (Koichi Sasada) over 5 years ago

Could you give us your idea with examples in pseudo-code?

Updated by chopraanmol1 (Anmol Chopra) over 5 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

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0