mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
perf(ext/fetch): use new instead of createBranded (#20624)
This PR optimizes `fromInner*` methods of `Request` / `Header` /
`Response` used by `Deno.serve` and `fetch` by using `new` instead of
`ObjectCreate` from `createBranded`.
The "brand" is created by passing `webidl.brand` to the constructor
instead.
142449ecab/ext/webidl/00_webidl.js (L1001-L1005)
### Benchmark
```js
const createBranded = Symbol("create branded");
const brand = Symbol("brand");
class B {
constructor(init) {
if (init === createBranded) {
this[brand] = brand;
}
}
}
Deno.bench("Object.create(protoype)", () => {
Object.create(B.prototype);
});
Deno.bench("new Class", () => {
new B(createBranded);
});
```
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.37.0 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------------------- -----------------------------
Object.create(protoype) 8.74 ns/iter 114,363,610.3 (7.32 ns … 26.02 ns) 8.65 ns 13.39 ns 14.47 ns
new Class 3.05 ns/iter 328,271,012.2 (2.78 ns … 9.1 ns) 3.06 ns 3.46 ns 3.5 ns
```
This commit is contained in:
parent
142449ecab
commit
65a94a6176
3 changed files with 24 additions and 6 deletions
|
@ -40,6 +40,7 @@ const _headerList = Symbol("header list");
|
|||
const _iterableHeaders = Symbol("iterable headers");
|
||||
const _iterableHeadersCache = Symbol("iterable headers cache");
|
||||
const _guard = Symbol("guard");
|
||||
const _brand = webidl.brand;
|
||||
|
||||
/**
|
||||
* @typedef Header
|
||||
|
@ -286,12 +287,17 @@ class Headers {
|
|||
|
||||
/** @param {HeadersInit} [init] */
|
||||
constructor(init = undefined) {
|
||||
if (init === _brand) {
|
||||
this[_brand] = _brand;
|
||||
return;
|
||||
}
|
||||
|
||||
const prefix = "Failed to construct 'Headers'";
|
||||
if (init !== undefined) {
|
||||
init = webidl.converters["HeadersInit"](init, prefix, "Argument 1");
|
||||
}
|
||||
|
||||
this[webidl.brand] = webidl.brand;
|
||||
this[_brand] = _brand;
|
||||
this[_guard] = "none";
|
||||
if (init !== undefined) {
|
||||
fillHeaders(this, init);
|
||||
|
@ -486,7 +492,7 @@ webidl.converters["Headers"] = webidl.createInterfaceConverter(
|
|||
* @returns {Headers}
|
||||
*/
|
||||
function headersFromHeaderList(list, guard) {
|
||||
const headers = webidl.createBranded(Headers);
|
||||
const headers = new Headers(_brand);
|
||||
headers[_headerList] = list;
|
||||
headers[_guard] = guard;
|
||||
return headers;
|
||||
|
|
|
@ -52,6 +52,7 @@ const _mimeType = Symbol("mime type");
|
|||
const _body = Symbol("body");
|
||||
const _url = Symbol("url");
|
||||
const _method = Symbol("method");
|
||||
const _brand = webidl.brand;
|
||||
|
||||
/**
|
||||
* @param {(() => string)[]} urlList
|
||||
|
@ -275,6 +276,11 @@ class Request {
|
|||
* @param {RequestInit} init
|
||||
*/
|
||||
constructor(input, init = {}) {
|
||||
if (input === _brand) {
|
||||
this[_brand] = _brand;
|
||||
return;
|
||||
}
|
||||
|
||||
const prefix = "Failed to construct 'Request'";
|
||||
webidl.requiredArguments(arguments.length, 1, prefix);
|
||||
input = webidl.converters["RequestInfo_DOMString"](
|
||||
|
@ -284,7 +290,7 @@ class Request {
|
|||
);
|
||||
init = webidl.converters["RequestInit"](init, prefix, "Argument 2");
|
||||
|
||||
this[webidl.brand] = webidl.brand;
|
||||
this[_brand] = _brand;
|
||||
|
||||
/** @type {InnerRequest} */
|
||||
let request;
|
||||
|
@ -554,7 +560,7 @@ function toInnerRequest(request) {
|
|||
* @returns {Request}
|
||||
*/
|
||||
function fromInnerRequest(inner, signal, guard) {
|
||||
const request = webidl.createBranded(Request);
|
||||
const request = new Request(_brand);
|
||||
request[_request] = inner;
|
||||
request[_signal] = signal;
|
||||
request[_getHeaders] = () => headersFromHeaderList(inner.headerList, guard);
|
||||
|
|
|
@ -60,6 +60,7 @@ const _response = Symbol("response");
|
|||
const _headers = Symbol("headers");
|
||||
const _mimeType = Symbol("mime type");
|
||||
const _body = Symbol("body");
|
||||
const _brand = webidl.brand;
|
||||
|
||||
/**
|
||||
* @typedef InnerResponse
|
||||
|
@ -305,6 +306,11 @@ class Response {
|
|||
* @param {ResponseInit} init
|
||||
*/
|
||||
constructor(body = null, init = undefined) {
|
||||
if (body === _brand) {
|
||||
this[_brand] = _brand;
|
||||
return;
|
||||
}
|
||||
|
||||
const prefix = "Failed to construct 'Response'";
|
||||
body = webidl.converters["BodyInit_DOMString?"](body, prefix, "Argument 1");
|
||||
init = webidl.converters["ResponseInit_fast"](init, prefix, "Argument 2");
|
||||
|
@ -320,7 +326,7 @@ class Response {
|
|||
bodyWithType = extractBody(body);
|
||||
}
|
||||
initializeAResponse(this, init, bodyWithType);
|
||||
this[webidl.brand] = webidl.brand;
|
||||
this[_brand] = _brand;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -489,7 +495,7 @@ function toInnerResponse(response) {
|
|||
* @returns {Response}
|
||||
*/
|
||||
function fromInnerResponse(inner, guard) {
|
||||
const response = webidl.createBranded(Response);
|
||||
const response = new Response(_brand);
|
||||
response[_response] = inner;
|
||||
response[_headers] = headersFromHeaderList(inner.headerList, guard);
|
||||
return response;
|
||||
|
|
Loading…
Reference in a new issue