Jean Boussier <[email protected]> wrote:
> > `match?' is Ruby 2.4+, which is probably too big a jump since
> > we're still on Ruby 1.9.3 at the moment...
>
> That's what I figured.
>
> > String comparison as in `==' and `!='? Would be interested to know
> > where and what improvements can be had.
Thanks for the benchmarks.
> One place that jumped to mind when I saw it is http_response_write.
> But there are many other places where Regexp are used to do case
> insensitive comparisons.
>
> ```
> require 'benchmark/ips'
>
> def http_response_write(headers)
> headers.each do |key, value|
> case key
> when %r{\A(?:Date|Connection)\z}i
> next
> end
> end
> end
>
> def http_response_write_upcase(headers)
> headers.each do |key, value|
> case key.upcase
> when 'DATE'.freeze, 'CONNECTION'.freeze
> next
> end
> end
> end
>
> def http_response_write_casecmp(headers)
> headers.each do |key, value|
> case key
> when key.casecmp?('Date'.freeze) || key.casecmp?('Connection'.freeze)
> next
> end
> end
> end
>
> HEADERS = {
> 'Foo' => 'bar',
> 'Date' => 'plop',
> 'User-Agent' => 'blah',
> }
>
> Benchmark.ips do |x|
> x.report('original') { http_response_write(HEADERS) }
> x.report('upcase') { http_response_write_upcase(HEADERS) }
> x.report('casecmp?') { http_response_write_casecmp(HEADERS) }
> x.compare!
> end
> ```
>
> ```
> Warming up --------------------------------------
> original 82.066k i/100ms
> upcase 177.429k i/100ms
> casecmp? 96.288k i/100ms
> Calculating -------------------------------------
> original 831.610k (± 1.6%) i/s - 4.185M in 5.034146s
> upcase 1.770M (± 1.6%) i/s - 8.871M in 5.013796s
> casecmp? 979.618k (± 1.3%) i/s - 4.911M in 5.013678s
>
> Comparison:
> upcase: 1769883.2 i/s
> casecmp?: 979618.3 i/s - 1.81x (± 0.00) slower
> original: 831610.2 i/s - 2.13x (± 0.00) slower
> ```
upcase seems VERY compelling in a micro benchmark since it can
go straight into opt_case_dispatch. But I worry the extra
garbage might have a different effect in a real app, especially
with more headers.
> Similarly, that method use `value =~ /\n/` which could be replaced
> favorably for `value.include?("\n".freeze)`
Yes, we tried that a few years ago and broke existing code
that had `nil' value, so it was promptly reverted:
https://yhbt.net/unicorn-public/CAO47=rJa=zrcln_xm4v2chpr6c0uswafc_omyfeh+basxho...@mail.gmail.com/
Maybe:
(val || ''.freeze).include?("\n".freeze)
Can work for those buggy apps, though...
> ```
> VAL = "foobar"
> Benchmark.ips do |x|
> x.report('=~') { VAL =~ /\n/ }
> x.report('include?') { VAL.include?("\n".freeze) }
> x.compare!
> end
> > Ruby just seems hopeless performance-wise
>
> Well, the gap between 1.9.3 and 2.5+ is pretty big performance-wise.
True, but it's still pretty slow :>
--
unsubscribe: one-click, see List-Unsubscribe header
archive: https://yhbt.net/unicorn-public/