summaryrefslogtreecommitdiff
path: root/ext/fetch/23_request.js
diff options
context:
space:
mode:
authorMarcos Casagrande <marcoscvp90@gmail.com>2023-08-12 20:29:00 +0200
committerGitHub <noreply@github.com>2023-08-12 12:29:00 -0600
commit050ca394096d22330bf5519aad2c59f84be7a0c2 (patch)
treef03c6374d8ce4f40125c110038566dc079ec55f6 /ext/fetch/23_request.js
parentb34bd640a686d11f8e8e3c3cee8d87980f7809f9 (diff)
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", }); }); ```
Diffstat (limited to 'ext/fetch/23_request.js')
-rw-r--r--ext/fetch/23_request.js45
1 files changed, 22 insertions, 23 deletions
diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js
index cfdce01d3..5232cc13c 100644
--- a/ext/fetch/23_request.js
+++ b/ext/fetch/23_request.js
@@ -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.