Conversation
When the VARY response header isn't set, there is no need to parse it
and examine it's content.
This improves the Deflater middleware by 20% when the header isn't set:
```ruby
require 'benchmark/ips'
require 'rack'
module Rack
class Deflater2 < Deflater
VARY = 'vary'
def call(env)
status, headers, body = response = @app.call(env)
unless should_deflate?(env, status, headers, body)
return response
end
request = Request.new(env)
encoding = Utils.select_best_encoding(%w(gzip identity),
request.accept_encoding)
# Set the Vary HTTP header.
if headers.has_key?(VARY)
vary = headers[VARY].to_s.split(",").map(&:strip)
unless vary.include?("*") || vary.any?{|v| v.downcase == 'accept-encoding'}
headers[VARY] = vary.push("Accept-Encoding").join(",")
end
else
headers[VARY] = "Accept-Encoding"
end
case encoding
when "gzip"
headers['content-encoding'] = "gzip"
headers.delete(CONTENT_LENGTH)
mtime = headers["last-modified"]
mtime = Time.httpdate(mtime).to_i if mtime
response[2] = GzipStream.new(body, mtime, @sync)
response
when "identity"
response
else # when nil
# Only possible encoding values here are 'gzip', 'identity', and nil
message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found."
bp = Rack::BodyProxy.new([message]) { body.close if body.respond_to?(:close) }
[406, { CONTENT_TYPE => "text/plain", CONTENT_LENGTH => message.length.to_s }, bp]
end
end
end
end
app = lambda do |env|
[200, {}, []]
end
deflater = Rack::Deflater.new(app, {})
deflater2 = Rack::Deflater2.new(app, {})
request = Rack::MockRequest.env_for('', {})
Benchmark.ips do |x|
x.config(warmup: 2, time: 5)
x.report("main") do
deflater.call(request)
end
x.report("branch") do
deflater2.call(request)
end
x.compare!
end
```
```
ruby 3.4.8 (2025-12-17 revision 995b59f666) +PRISM [arm64-darwin24]
Warming up --------------------------------------
main 94.625k i/100ms
branch 115.769k i/100ms
Calculating -------------------------------------
main 950.471k (± 1.0%) i/s (1.05 μs/i) - 4.826M in 5.077838s
branch 1.173M (± 1.3%) i/s (852.46 ns/i) - 5.904M in 5.034024s
Comparison:
branch: 1173071.0 i/s
main: 950471.1 i/s - 1.23x slower
```
p8
force-pushed
the
performance/deflater-vary
branch
from
May 5, 2026 11:07
4ef9238 to
4316fe9
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When the VARY response header isn't set, there is no need to parse it and examine its content.
This improves the Deflater middleware by 20% when the header isn't set: