unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
From: Eric Wong <e@yhbt.net>
To: Jean Boussier <jean.boussier@shopify.com>
Cc: unicorn-public@yhbt.net
Subject: Re: [PATCH] Add early hints support
Date: Mon, 20 Jul 2020 10:55:38 +0000	[thread overview]
Message-ID: <20200720105538.GA13340@dcvr> (raw)
In-Reply-To: <F908D215-8646-450C-BA7F-9704F1E9D738@shopify.com>

Jean Boussier <jean.boussier@shopify.com> 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+baSxHOWKQ@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 :>

  reply	other threads:[~2020-07-20 10:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-16 10:05 Jean Boussier
2020-07-16 10:50 ` Eric Wong
2020-07-16 11:41   ` Jean Boussier
2020-07-16 12:16     ` Eric Wong
2020-07-16 12:24       ` Jean Boussier
2020-07-17  1:19         ` Eric Wong
2020-07-20  9:18           ` Jean Boussier
2020-07-20 10:09             ` Eric Wong
2020-07-20 10:27               ` Jean Boussier
2020-07-20 10:55                 ` Eric Wong [this message]
2020-07-20 11:53                   ` Jean Boussier
2020-07-20 20:27                     ` Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://yhbt.net/unicorn/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200720105538.GA13340@dcvr \
    --to=e@yhbt.net \
    --cc=jean.boussier@shopify.com \
    --cc=unicorn-public@yhbt.net \
    --subject='Re: [PATCH] Add early hints support' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Code repositories for project(s) associated with this inbox:

	../../unicorn.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).