summary refs log tree commit
path: root/lib/rack/conditionalget.rb
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2014-10-05 07:58:16 +0000
committerEric Wong <e@80x24.org>2014-10-05 08:09:50 +0000
commit68e086d2b42ee2c9fc8017264aa353a0d543fd13 (patch)
treecd0d3f86173ae78ea1d2200d3a812d090b367b3f /lib/rack/conditionalget.rb
parent022b0076b0eacad03eac48060198f05aa776a866 (diff)
downloadrack-68e086d2b42ee2c9fc8017264aa353a0d543fd13.tar.gz
conditionalget: avoid const lookup in case/when HEAD when-lit master
case/when dispatches already optimize away allocation of constant
string literals in all C Ruby 1.9.x/2.x releases
(ref: opt_case_dispatch in Ruby insns.def)

Other Ruby implementations presumably have similar optimizations
to encourage prettier code.

The following code snippet does not cause GC.count to increase
during the two loops, regardless of what `nr' is.
Tested on Ruby 1.9.3, 2.1.3, and trunk r47786:

    GET = "GET"
    HEAD = "HEAD"
    REQUEST_METHOD = "REQUEST_METHOD" # unnecessary in 2.2.0+
    env = { REQUEST_METHOD => "GET" }

    nr = 10000000
    nr.times do |i|
      case env[REQUEST_METHOD]
      when GET, HEAD
        :foo
      else
        :bar
      end
    end
    a = GC.count

    nr.times do |i|
      case env[REQUEST_METHOD]
      when "GET", "HEAD"
        :foo
      else
        :bar
      end
    end
    b = GC.count
    p [ a, b ]
Diffstat (limited to 'lib/rack/conditionalget.rb')
-rw-r--r--lib/rack/conditionalget.rb2
1 files changed, 1 insertions, 1 deletions
diff --git a/lib/rack/conditionalget.rb b/lib/rack/conditionalget.rb
index 3d4c78aa..441dd382 100644
--- a/lib/rack/conditionalget.rb
+++ b/lib/rack/conditionalget.rb
@@ -21,7 +21,7 @@ module Rack
 
     def call(env)
       case env[REQUEST_METHOD]
-      when GET, HEAD
+      when "GET", "HEAD"
         status, headers, body = @app.call(env)
         headers = Utils::HeaderHash.new(headers)
         if status == 200 && fresh?(env, headers)