summaryrefslogtreecommitdiff
path: root/ext/http/http_next.rs
diff options
context:
space:
mode:
authorMarcos Casagrande <marcoscvp90@gmail.com>2023-09-16 23:15:15 +0200
committerGitHub <noreply@github.com>2023-09-16 15:15:15 -0600
commit16b7c9cd8d0b23ea51ad0070c7589ebefb3d51fa (patch)
tree840e66f9ddf3208d45f3b132d273e84cc76b2aa7 /ext/http/http_next.rs
parentd13e6e6db8b3d3f1b8a4e86492e406c3c42d2a9d (diff)
perf(ext/http): optimize `set_response` for small responses (#20527)
This PR introduces an optimization to `set_response` to reduce the overhead for responses with a payload size less than 64 bytes. Performance gains are more noticeable when `is_request_compressible` enters the slow path, ie: `-H 'Accept-Encoding: unknown'` ### Benchmarks ```js Deno.serve({ port: 3000 }, () => new Response("hello")); ``` ``` wrk -d 10s --latency -H 'Accept-Encoding: slow' http://127.0.0.1:3000 ``` --- **main** ``` Running 10s test @ http://127.0.0.1:3000 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 44.72us 28.12us 3.10ms 97.95% Req/Sec 112.73k 8.25k 123.66k 91.09% 2264092 requests in 10.10s, 308.77MB read Requests/sec: 224187.08 Transfer/sec: 30.57MB ``` **this PR** ``` Running 10s test @ http://127.0.0.1:3000 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 42.91us 20.57us 2.04ms 97.36% Req/Sec 116.61k 7.95k 204.81k 88.56% 2330970 requests in 10.10s, 317.89MB read Requests/sec: 230806.32 Transfer/sec: 31.48MB ```
Diffstat (limited to 'ext/http/http_next.rs')
-rw-r--r--ext/http/http_next.rs31
1 files changed, 16 insertions, 15 deletions
diff --git a/ext/http/http_next.rs b/ext/http/http_next.rs
index 94f6f1241..c6e3ac384 100644
--- a/ext/http/http_next.rs
+++ b/ext/http/http_next.rs
@@ -463,7 +463,18 @@ pub fn op_http_set_response_trailers(
*http.trailers().borrow_mut() = Some(trailer_map);
}
-fn is_request_compressible(headers: &HeaderMap) -> Compression {
+fn is_request_compressible(
+ length: Option<usize>,
+ headers: &HeaderMap,
+) -> Compression {
+ if let Some(length) = length {
+ // By the time we add compression headers and Accept-Encoding, it probably doesn't make sense
+ // to compress stuff that's smaller than this.
+ if length < 64 {
+ return Compression::None;
+ }
+ }
+
let Some(accept_encoding) = headers.get(ACCEPT_ENCODING) else {
return Compression::None;
};
@@ -521,17 +532,9 @@ fn is_response_compressible(headers: &HeaderMap) -> bool {
fn modify_compressibility_from_response(
compression: Compression,
- length: Option<usize>,
headers: &mut HeaderMap,
) -> Compression {
ensure_vary_accept_encoding(headers);
- if let Some(length) = length {
- // By the time we add compression headers and Accept-Encoding, it probably doesn't make sense
- // to compress stuff that's smaller than this.
- if length < 64 {
- return Compression::None;
- }
- }
if compression == Compression::None {
return Compression::None;
}
@@ -592,13 +595,11 @@ fn set_response(
// do all of this work to send the response.
if !http.cancelled() {
let resource = http.take_resource();
- let compression = is_request_compressible(&http.request_parts().headers);
+ let compression =
+ is_request_compressible(length, &http.request_parts().headers);
let response = http.response();
- let compression = modify_compressibility_from_response(
- compression,
- length,
- response.headers_mut(),
- );
+ let compression =
+ modify_compressibility_from_response(compression, response.headers_mut());
response
.body_mut()
.initialize(response_fn(compression), resource);