Skip to content

Commit

Permalink
perf(ext/headers): use regex.test instead of .exec (#20125)
Browse files Browse the repository at this point in the history
This PR improves the performance of `Headers.get` by using `Regex.test`
instead of `.exec`. Also replaced the `Map` used for caching with an
object which is a bit faster

**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.get           124.71 ns/iter   8,018,687.3 (115.11 ns … 265.66 ns) 126.05 ns 136.12 ns 142.37 ns
```

**1.36.1**

```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.36.0 (x86_64-unknown-linux-gnu)

benchmark              time (avg)        iter/s             (min … max)       p75       p99      p995
----------------------------------------------------------------------- -----------------------------
Headers.get           218.91 ns/iter   4,568,172.3 (165.37 ns … 264.44 ns) 241.62 ns 260.94 ns 262.67 ns
```

```js
const headers = new Headers({
  "Content-Type": "application/json",
  "Date": "Thu, 10 Aug 2023 07:45:10 GMT",
  "X-Deno": "Deno",
  "Powered-By": "Deno",
  "Content-Encoding": "gzip",
  "Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com",
  "Content-Length": "150",
  "Vary": "Accept-Encoding, Accept, X-Requested-With",
});

Deno.bench("Headers.get", () => {
  headers.get("x-deno");
});
```
  • Loading branch information
marcosc90 authored and littledivy committed Aug 21, 2023
1 parent aaa3608 commit d0525dd
Showing 1 changed file with 12 additions and 13 deletions.
25 changes: 12 additions & 13 deletions ext/fetch/20_headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ const {
ArrayPrototypeSplice,
ObjectEntries,
ObjectHasOwn,
RegExpPrototypeExec,
SafeMap,
MapPrototypeGet,
MapPrototypeHas,
MapPrototypeSet,
MapPrototypeClear,
RegExpPrototypeTest,
Symbol,
SymbolFor,
SymbolIterator,
Expand Down Expand Up @@ -102,19 +97,23 @@ function checkForInvalidValueChars(value) {
return true;
}

const HEADER_NAME_CACHE = new SafeMap();
let HEADER_NAME_CACHE = {};
let HEADER_CACHE_SIZE = 0;
const HEADER_NAME_CACHE_SIZE_BOUNDARY = 4096;
function checkHeaderNameForHttpTokenCodePoint(name) {
if (MapPrototypeHas(HEADER_NAME_CACHE, name)) {
return MapPrototypeGet(HEADER_NAME_CACHE, name);
const fromCache = HEADER_NAME_CACHE[name];
if (fromCache !== undefined) {
return fromCache;
}

const valid = RegExpPrototypeExec(HTTP_TOKEN_CODE_POINT_RE, name) !== null;
const valid = RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name);

if (HEADER_NAME_CACHE.size > HEADER_NAME_CACHE_SIZE_BOUNDARY) {
MapPrototypeClear(HEADER_NAME_CACHE);
if (HEADER_CACHE_SIZE > HEADER_NAME_CACHE_SIZE_BOUNDARY) {
HEADER_NAME_CACHE = {};
HEADER_CACHE_SIZE = 0;
}
MapPrototypeSet(HEADER_NAME_CACHE, name, valid);
HEADER_CACHE_SIZE++;
HEADER_NAME_CACHE[name] = valid;

return valid;
}
Expand Down

0 comments on commit d0525dd

Please sign in to comment.