mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
perf(ext/request): optimize validate and normalize HTTP method (#20143)
This PR optimizes `Request` constructor init method step. It doubles the speed for known lowercased methods. I also added `PATCH` to known methods **this patch** ``` benchmark time (avg) iter/s (min … max) p75 p99 p995 ---------------------------------------------------------------------------- ----------------------------- method: GET 1.49 µs/iter 669,336.9 (1.35 µs … 2.02 µs) 1.54 µs 2.02 µs 2.02 µs method: PATCH 1.85 µs/iter 540,921.5 (1.65 µs … 2.02 µs) 1.91 µs 2.02 µs 2.02 µs method: get 1.49 µs/iter 669,067.9 (1.28 µs … 1.69 µs) 1.55 µs 1.69 µs 1.69 µs ``` **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 ---------------------------------------------------------------------------- ----------------------------- method: GET 1.5 µs/iter 665,232.3 (1.3 µs … 2.02 µs) 1.54 µs 2.02 µs 2.02 µs method: PATCH 2.47 µs/iter 404,052.7 (2.06 µs … 4.05 µs) 2.51 µs 4.05 µs 4.05 µs method: get 3 µs/iter 333,277.2 (2.72 µs … 4.04 µs) 3.05 µs 4.04 µs 4.04 µs ``` ```js Deno.bench("method: GET", () => { const r = new Request("https://deno.land", { method: "GET", }); }); Deno.bench("method: PATCH", () => { const r = new Request("https://deno.land", { method: "PATCH", body: '{"foo": "bar"}', }); }); Deno.bench("method: get", () => { const r = new Request("https://deno.land", { method: "get", }); }); ```
This commit is contained in:
parent
d0525dd692
commit
4e08665973
1 changed files with 22 additions and 23 deletions
|
@ -202,31 +202,29 @@ function cloneInnerRequest(request, skipBody = false) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} m
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isKnownMethod(m) {
|
||||
return (
|
||||
m === "DELETE" ||
|
||||
m === "GET" ||
|
||||
m === "HEAD" ||
|
||||
m === "OPTIONS" ||
|
||||
m === "POST" ||
|
||||
m === "PUT"
|
||||
);
|
||||
}
|
||||
// method => normalized method
|
||||
const KNOWN_METHODS = {
|
||||
"DELETE": "DELETE",
|
||||
"delete": "DELETE",
|
||||
"GET": "GET",
|
||||
"get": "GET",
|
||||
"HEAD": "HEAD",
|
||||
"head": "HEAD",
|
||||
"OPTIONS": "OPTIONS",
|
||||
"options": "OPTIONS",
|
||||
"PATCH": "PATCH",
|
||||
"patch": "PATCH",
|
||||
"POST": "POST",
|
||||
"post": "POST",
|
||||
"PUT": "PUT",
|
||||
"put": "PUT",
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} m
|
||||
* @returns {string}
|
||||
*/
|
||||
function validateAndNormalizeMethod(m) {
|
||||
// Fast path for well-known methods
|
||||
if (isKnownMethod(m)) {
|
||||
return m;
|
||||
}
|
||||
|
||||
// Regular path
|
||||
if (RegExpPrototypeExec(HTTP_TOKEN_CODE_POINT_RE, m) === null) {
|
||||
throw new TypeError("Method is not valid.");
|
||||
}
|
||||
|
@ -325,9 +323,10 @@ class Request {
|
|||
|
||||
// 25.
|
||||
if (init.method !== undefined) {
|
||||
let method = init.method;
|
||||
method = validateAndNormalizeMethod(method);
|
||||
request.method = method;
|
||||
const method = init.method;
|
||||
// fast path: check for known methods
|
||||
request.method = KNOWN_METHODS[method] ??
|
||||
validateAndNormalizeMethod(method);
|
||||
}
|
||||
|
||||
// 26.
|
||||
|
|
Loading…
Reference in a new issue