From: Eric Wong Date: 2015-08-04T03:09:14+00:00 Subject: [ruby-core:70234] Re: [Ruby trunk - Feature #11375] Decreased Object Allocation in Pathname.rb Eric Wong wrote: > richard.schneeman@gmail.com wrote: > > You've mentioned the case statement optimization previously in a patch I sent to Rack. I agree that the difference is pretty negligible. Although I'm able to consistently see one running `benchmark/ips` > > Thanks. We need to see if we can optimize case/when for smaller > statements. It looks to be a problem with st_lookup (from > opt_case_dispatch) being pointless for small case/when statements. > > Perhaps try something like the following patch to compile.c NAK on my own patch to compile.c st_lookup is still faster when there is no match in the case/when, or when there's multiple "when" statements. So I think the only place where a literal freeze for a "when" is faster is when there's a guaranteed hit, and only one element to match against (as in [ruby-core:70103]). In every other case, emitting the opt_case_dispatch insn seems faster. Benchmarks I used for testing this: diff --git a/benchmark/bm_vm2_case_opt1.rb b/benchmark/bm_vm2_case_opt1.rb new file mode 100644 index 0000000..e804d4b --- /dev/null +++ b/benchmark/bm_vm2_case_opt1.rb @@ -0,0 +1,9 @@ +# [ruby-core:70103] +i = 0 +string = 'foo' +while i<6_000_000 # while loop 2 + case string + when 'foo' + i += 1 + end +end diff --git a/benchmark/bm_vm2_case_opt1miss.rb b/benchmark/bm_vm2_case_opt1miss.rb new file mode 100644 index 0000000..800f8f1 --- /dev/null +++ b/benchmark/bm_vm2_case_opt1miss.rb @@ -0,0 +1,10 @@ +# [ruby-core:70103] +i = 0 +string = 'foo' +while i<6_000_000 # while loop 2 + case string + when 'FOO' + i += 1 + end + i += 1 +end diff --git a/benchmark/bm_vm2_case_opt2.rb b/benchmark/bm_vm2_case_opt2.rb new file mode 100644 index 0000000..774892e --- /dev/null +++ b/benchmark/bm_vm2_case_opt2.rb @@ -0,0 +1,11 @@ +# [ruby-core:70103] +i = 0 +string = 'foo' +while i<6_000_000 # while loop 2 + case string + when 'bar' + i -= 1 + when 'foo' + i += 1 + end +end diff --git a/benchmark/bm_vm2_case_opt2miss.rb b/benchmark/bm_vm2_case_opt2miss.rb new file mode 100644 index 0000000..de820ae --- /dev/null +++ b/benchmark/bm_vm2_case_opt2miss.rb @@ -0,0 +1,12 @@ +# [ruby-core:70103] +i = 0 +string = 'foo' +while i<6_000_000 # while loop 2 + case string + when 'bar' + i -= 1 + when 'FOO' + i += 1 + end + i += 1 +end