mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
perf(ext/headers): cache iterableHeaders for immutable Headers (#20132)
This PR caches `_iterableHeaders` for immutable `Headers` increasing the performance of `fetch` & server if headers are iterated. Should close #19466 I only cached immutable headers to address this comment https://github.com/denoland/deno/issues/19466#issuecomment-1589892373 since I didn't find any occurrence of header mutation on immutable headers. We can discuss caching for non-immutable, but I think this is a great first step. ## BENCHMARK ### Server ```js const addr = Deno.args[0] ?? "127.0.0.1:4500"; const [hostname, port] = addr.split(":"); const { serve } = Deno; serve({ hostname, port: Number(port), reusePort: true }, (req) => { const headers = [...req.headers]; // req.headers are immutable, cannot set/append/delete return new Response("ok"); }); ``` Used `wrk` with 5 headers ``` wrk -d 10s --latency -H "X-Deno: true" -H "Accept: application/json" -H "X-Foo: bar" -H "User-Agent: wrk" -H "Accept-Encoding: gzip, br" http://127.0.0.1:4500 ``` **This patch** ``` Running 10s test @ http://127.0.0.1:4500 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 70.18us 22.89us 679.00us 81.37% Req/Sec 71.55k 9.69k 82.18k 89.60% Latency Distribution 50% 59.00us 75% 89.00us 90% 98.00us 99% 159.00us 1437891 requests in 10.10s, 193.35MB read Requests/sec: 142369.83 Transfer/sec: 19.14MB ``` **main** ``` Running 10s test @ http://127.0.0.1:4500 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 112.78us 36.47us 2.09ms 77.99% Req/Sec 44.30k 1.65k 49.14k 74.26% Latency Distribution 50% 99.00us 75% 136.00us 90% 162.00us 99% 213.00us 890588 requests in 10.10s, 118.91MB read Requests/sec: 88176.37 Transfer/sec: 11.77MB ``` ### fetch ```js const res = await fetch('http://127.0.0.1:4500'); Deno.bench("Headers iterator", () => { const i = [...res.headers]; // res.headers are immutable, cannot set/append/delete }); ``` **this patch** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ---------------------------------------------------------------------- ----------------------------- Headers iterator 329.5 ns/iter 3,034,909.0 (318.55 ns … 364.34 ns) 331.1 ns 355.72 ns 364.34 ns ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ---------------------------------------------------------------------- ----------------------------- Headers iterator 2.59 µs/iter 386,372.1 (2.56 µs … 2.68 µs) 2.59 µs 2.68 µs 2.68 µs ```
This commit is contained in:
parent
bf9ddb7c2e
commit
aaa3608cc1
1 changed files with 13 additions and 1 deletions
|
@ -44,6 +44,7 @@ const {
|
|||
|
||||
const _headerList = Symbol("header list");
|
||||
const _iterableHeaders = Symbol("iterable headers");
|
||||
const _iterableHeadersCache = Symbol("iterable headers cache");
|
||||
const _guard = Symbol("guard");
|
||||
|
||||
/**
|
||||
|
@ -229,6 +230,13 @@ class Headers {
|
|||
get [_iterableHeaders]() {
|
||||
const list = this[_headerList];
|
||||
|
||||
if (
|
||||
this[_guard] === "immutable" &&
|
||||
this[_iterableHeadersCache] !== undefined
|
||||
) {
|
||||
return this[_iterableHeadersCache];
|
||||
}
|
||||
|
||||
// The order of steps are not similar to the ones suggested by the
|
||||
// spec but produce the same result.
|
||||
const headers = {};
|
||||
|
@ -264,7 +272,7 @@ class Headers {
|
|||
ArrayPrototypePush(entries, cookies[i]);
|
||||
}
|
||||
|
||||
return ArrayPrototypeSort(
|
||||
ArrayPrototypeSort(
|
||||
entries,
|
||||
(a, b) => {
|
||||
const akey = a[0];
|
||||
|
@ -274,6 +282,10 @@ class Headers {
|
|||
return 0;
|
||||
},
|
||||
);
|
||||
|
||||
this[_iterableHeadersCache] = entries;
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
/** @param {HeadersInit} [init] */
|
||||
|
|
Loading…
Reference in a new issue