Perfactoring - Phase_02


### Before

```
$ httperf --hog --port 9292 --num-conns=1 --num-calls=1000
...
Request rate: 4204.4 req/s (0.2 ms/req)
...
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0
```

### After

```
$ httperf --hog --port 9292 --num-conns=1 --num-calls=1000
...
Request rate: 5474.9 req/s (0.2 ms/req)
...
Reply status: 1xx=0 2xx=1000 3xx=0 4xx=0 5xx=0
```

### Commenting on most notable updates

```
diff --git a/lib/reel/request.rb b/lib/reel/request.rb


# not needed anymore, data will be accessed directly from parser
-    attr_accessor :method, :version, :url, :headers
+    include RequestMixin
 
     UPGRADE   = 'Upgrade'.freeze
     WEBSOCKET = 'websocket'.freeze
 
# Array#include? seems slow compared to Hash lookup
# so building a hash map at loadtime and querying it at runtime
+    request_methods = Http::METHODS.map { |m| m.to_s.upcase }
+    REQUEST_METHODS = Hash[request_methods.zip(request_methods)].freeze
+


# this decrease performance by about 400-500 rps
# and i guess it is redundant cause in RackWorker
# we prepare headers in Rack way.
# and if we will feed headers to other framework,
# we will prepare headers in there worker.
-      headers = {}
-      parser.headers.each do |field, value|
-        headers[Http.canonicalize_header(field)] = value
-      end

# querying request methods map built at loadtime
+      REQUEST_METHODS[parser.http_method] ||
+        raise(ArgumentError, "Unknown Request Method: %s" % parser.http_method)

# passing parser directly into Request and WebSocket classes.
# this way we will can access parser data without redundant accessors.
# also, by accessing request_path and query_string directly from parser
# removes the overhead needed to build and query a separate URI object.
-      upgrade = headers[UPGRADE]
+      upgrade = parser.headers[UPGRADE]
       if upgrade && upgrade.downcase == WEBSOCKET
-        WebSocket.new(connection.socket, parser.http_method, parser.url, headers)
+        WebSocket.new(parser, connection.socket)
       else
-        Request.new(parser.http_method, parser.url, parser.http_version, headers, connection)
+        Request.new(parser, connection)
       end
     end

diff --git a/lib/reel/request_parser.rb b/lib/reel/request_parser.rb


# adding methods that will allow to access 
# request_path and query_string directly from parser
+      [:request_path, :query_string].each do |m|
+        define_method m do
+          @parser.send m
+        end
+      end
+


# Http::METHODS not used anymore at runtime so no need to coerce string into sym.
# instead we building a map at loadtime that contains all methods as uppercase strings
       def http_method
-        @parser.http_method.downcase.to_sym
+        @parser.http_method
       end

# joining fixnums is really slow.
# fixnum comparing instead if really fast.
# might looks strange, but according to perftools.rb
# this removed a notable overhead
       def http_version
-        @parser.http_version.join(".")
-        # TODO: add extra HTTP_VERSION handler when HTTP/1.2 released
+        @parser.http_version[1] == 1 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0
       end
 


diff --git a/lib/reel/response.rb b/lib/reel/response.rb

# though this adds notable overhead, 
# we have to behave well and normalize headers before sending them to browser.
# however extra regexing are really redundant here 
# and adds even more  overhead, so just removed it.
       @headers = {}
-      headers.each do |name, value|
-        name = name.to_s
-        key = name[Http::CANONICAL_HEADER]
-        key ||= canonicalize_header(name)
-        @headers[key] = value.to_s
+      headers.each_pair do |header, value|
+        @headers[Http.canonicalize_header(header)] = value.to_s
       end

-    # Transform to canonical HTTP header capitalization
-    def canonicalize_header(header)
-      header.to_s.split(/[\-_]/).map(&:capitalize).join('-')
-    end
-    private :canonicalize_header
   end
 end


diff --git a/lib/reel/mixins.rb b/lib/reel/mixins.rb

module RequestMixin
...

# accessing path and query string directly from parser 
# will avoid overhead needed to create and query a new URI object
  def path
    @http_parser.request_path
  end

  def query_string
    @http_parser.query_string
  end

end
```