Skip to content
  • Petrik's avatar
    18cb9092
    Don't parse response content type if value comes from Mime · 18cb9092
    Petrik authored
    Anytime `ActionDispatch::HTTP::Reponse#content_type=` is called, the
    `content_type` argument is parsed using the CONTENT_TYPE_PARSER regexp.
    If the `content_type` argument comes from `Mime`, there is no need to
    parse it using the regexp as we already know the result.
    
    ```ruby
    require "bundler/inline"
    
    gemfile(true) do
      source "https://rubygems.org"
    
      gem "rails"
      gem "benchmark-ips"
    end
    
    require "action_controller/railtie"
    require 'benchmark/ips'
    
    Benchmark.ips do |x|
      x.config(:time => 5, :warmup => 2)
    
      response = ActionDispatch::Response.new
      x.report("main") do
        response.content_type = Mime[:html].to_s
      end
    
      class BranchResponse < ActionDispatch::Response
        def content_type=(content_type)
          case content_type
          when NilClass
            return
          when Symbol
            new_header_info = ContentTypeHeader.new(Mime[content_type])
          else
            new_header_info = parse_content_type(content_type.to_s)
          end
    
          prev_header_info = parsed_content_type_header
          charset = new_header_info.charset || prev_header_info.charset
          charset ||= self.class.default_charset unless prev_header_info.mime_type
          set_content_type new_header_info.mime_type, charset
        end
      end
    
      response = BranchResponse.new
      x.report("branch") do
        response.content_type = :html
      end
    
      x.compare!
    end
    ```
    
    ```
    Warming up --------------------------------------
                    main    38.666k i/100ms
                  branch    52.235k i/100ms
    Calculating -------------------------------------
                    main    393.529k (± 3.3%) i/s    (2.54 μs/i) -      1.972M in   5.016529s
                  branch    494.789k (± 2.2%) i/s    (2.02 μs/i) -      2.507M in   5.069774s
    
    Comparison:
                  branch:   494788.6 i/s
                    main:   393529.2 i/s - 1.26x  slower
    ```
    
    This improves the plain json call in the TechEmpower benchmark by
    reducing the time spent in `#assign_default_content_type_and_charset!`
    from 16% to 6.5%.
    It probably improves other calls as well.
    18cb9092
    Don't parse response content type if value comes from Mime
    Petrik authored
    Anytime `ActionDispatch::HTTP::Reponse#content_type=` is called, the
    `content_type` argument is parsed using the CONTENT_TYPE_PARSER regexp.
    If the `content_type` argument comes from `Mime`, there is no need to
    parse it using the regexp as we already know the result.
    
    ```ruby
    require "bundler/inline"
    
    gemfile(true) do
      source "https://rubygems.org"
    
      gem "rails"
      gem "benchmark-ips"
    end
    
    require "action_controller/railtie"
    require 'benchmark/ips'
    
    Benchmark.ips do |x|
      x.config(:time => 5, :warmup => 2)
    
      response = ActionDispatch::Response.new
      x.report("main") do
        response.content_type = Mime[:html].to_s
      end
    
      class BranchResponse < ActionDispatch::Response
        def content_type=(content_type)
          case content_type
          when NilClass
            return
          when Symbol
            new_header_info = ContentTypeHeader.new(Mime[content_type])
          else
            new_header_info = parse_content_type(content_type.to_s)
          end
    
          prev_header_info = parsed_content_type_header
          charset = new_header_info.charset || prev_header_info.charset
          charset ||= self.class.default_charset unless prev_header_info.mime_type
          set_content_type new_header_info.mime_type, charset
        end
      end
    
      response = BranchResponse.new
      x.report("branch") do
        response.content_type = :html
      end
    
      x.compare!
    end
    ```
    
    ```
    Warming up --------------------------------------
                    main    38.666k i/100ms
                  branch    52.235k i/100ms
    Calculating -------------------------------------
                    main    393.529k (± 3.3%) i/s    (2.54 μs/i) -      1.972M in   5.016529s
                  branch    494.789k (± 2.2%) i/s    (2.02 μs/i) -      2.507M in   5.069774s
    
    Comparison:
                  branch:   494788.6 i/s
                    main:   393529.2 i/s - 1.26x  slower
    ```
    
    This improves the plain json call in the TechEmpower benchmark by
    reducing the time spent in `#assign_default_content_type_and_charset!`
    from 16% to 6.5%.
    It probably improves other calls as well.
Loading