diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-12-10 21:33:53 -0600 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2009-12-10 21:33:53 -0600 |
commit | cdf13618445fa7065c07d62b115907856d6d1095 (patch) | |
tree | a0b6b919f56f6b8b30bc5dc7b54b401e26a32a9e | |
parent | a9440bc752be9b3093669614c6b56bf78d592958 (diff) | |
download | rack-cdf13618445fa7065c07d62b115907856d6d1095.tar.gz |
HeaderHash.new avoids unnecessary object creation
Creating a new HeaderHash is an O(n) operation in addition to the cost of allocating a new object. When using multiple pieces of middleware, this can lead to unnecessary memory allocation and iteration overhead. We now explicitly define the HeaderHash.new class method to return its original argument if it is already a HeaderHash to avoid repeating work. Signed-off-by: Joshua Peek <josh@joshpeek.com>
-rw-r--r-- | lib/rack/utils.rb | 4 | ||||
-rw-r--r-- | test/spec_rack_utils.rb | 8 |
2 files changed, 12 insertions, 0 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index b5aa8a19..4956177e 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -263,6 +263,10 @@ module Rack # A case-insensitive Hash that preserves the original case of a # header when set. class HeaderHash < Hash + def self.new(hash={}) + HeaderHash === hash ? hash : super(hash) + end + def initialize(hash={}) super() @names = {} diff --git a/test/spec_rack_utils.rb b/test/spec_rack_utils.rb index 0a73d18c..755a1619 100644 --- a/test/spec_rack_utils.rb +++ b/test/spec_rack_utils.rb @@ -273,6 +273,14 @@ context "Rack::Utils::HeaderHash" do h = Rack::Utils::HeaderHash.new("foo" => "bar") h.delete("Hello").should.be.nil end + + specify "should avoid unnecessary object creation if possible" do + a = Rack::Utils::HeaderHash.new("foo" => "bar") + b = Rack::Utils::HeaderHash.new(a) + b.object_id.should.equal(a.object_id) + b.should.equal(a) + end + end context "Rack::Utils::Context" do |