diff options
author | Marcos Casagrande <marcos@denode.com> | 2023-10-02 02:18:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-02 02:18:34 +0200 |
commit | de25c81fd0860d0fb604d105534721d8b37a4abd (patch) | |
tree | 4dc517d88725d477d02ddb141816f0cdd360bf45 | |
parent | 8d24be1a59714761665516e0d78d25059608c29b (diff) |
perf(ext/web): optimize DOMException (#20715)
This PR optimizes `DOMException` constructor increasing performance of
all Web APIs that throw a `DOMException` (ie: `AbortSignal`)
**main**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.37.1 (x86_64-unknown-linux-gnu)
new DOMException() 9.66 µs/iter 103,476.8 (8.47 µs … 942.71 µs) 9.62 µs 11.29 µs 14.04 µs
abort writeTextFileSync 16.45 µs/iter 60,775.5 (13.65 µs … 1.33 ms) 16.39 µs 20.59 µs 24.12 µs
abort readFile 16.25 µs/iter 61,542.2 (15.12 µs … 621.14 µs) 16.18 µs 19.59 µs 22.33 µs
```
**this PR**
```
cpu: 13th Gen Intel(R) Core(TM) i9-13900H
runtime: deno 1.37.1 (x86_64-unknown-linux-gnu)
benchmark time (avg) iter/s (min … max) p75 p99 p995
----------------------------------------------------------------------------- -----------------------------
new DOMException() 2.37 µs/iter 421,657.0 (2.33 µs … 2.58 µs) 2.37 µs 2.58 µs 2.58 µs
abort writeTextFileSync 7.1 µs/iter 140,760.1 (6.94 µs … 7.68 µs) 7.13 µs 7.68 µs 7.68 µs
abort readFile 5.48 µs/iter 182,648.2 (5.3 µs … 5.69 µs) 5.56 µs 5.69 µs 5.69 µ
```
```js
Deno.bench("new DOMException()", () => {
new DOMException();
});
Deno.bench("abort writeTextFileSync", () => {
const ac = new AbortController();
ac.abort();
try {
Deno.writeTextFileSync("/tmp/out", "x", { signal: ac.signal });
} catch {}
});
Deno.bench("abort readFile", async () => {
const ac = new AbortController();
ac.abort();
try {
await Deno.readFile("/tmp/out", { signal: ac.signal });
} catch {}
});
```
-rw-r--r-- | ext/web/01_dom_exception.js | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/ext/web/01_dom_exception.js b/ext/web/01_dom_exception.js index 31d2cdc29..54d47beaf 100644 --- a/ext/web/01_dom_exception.js +++ b/ext/web/01_dom_exception.js @@ -26,6 +26,7 @@ import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; const _name = Symbol("name"); const _message = Symbol("message"); const _code = Symbol("code"); +const _error = Symbol("error"); // Defined in WebIDL 4.3. // https://webidl.spec.whatwg.org/#idl-DOMException @@ -111,21 +112,8 @@ class DOMException { this[_code] = code; this[webidl.brand] = webidl.brand; - const error = new Error(message); - error.name = "DOMException"; - ObjectDefineProperty(this, "stack", { - value: error.stack, - writable: true, - configurable: true, - }); - - // `DOMException` isn't a native error, so `Error.prepareStackTrace()` is - // not called when accessing `.stack`, meaning our structured stack trace - // hack doesn't apply. This patches it in. - ObjectDefineProperty(this, "__callSiteEvals", { - value: ArrayPrototypeSlice(error.__callSiteEvals, 1), - configurable: true, - }); + this[_error] = new Error(message); + this[_error].name = "DOMException"; } get message() { @@ -160,6 +148,26 @@ class DOMException { } } +ObjectDefineProperty(DOMException.prototype, "stack", { + get() { + return this[_error].stack; + }, + set(value) { + this[_error].stack = value; + }, + configurable: true, +}); + +// `DOMException` isn't a native error, so `Error.prepareStackTrace()` is +// not called when accessing `.stack`, meaning our structured stack trace +// hack doesn't apply. This patches it in. +ObjectDefineProperty(DOMException.prototype, "__callSiteEvals", { + get() { + return ArrayPrototypeSlice(this[_error].__callSiteEvals, 1); + }, + configurable: true, +}); + ObjectSetPrototypeOf(DOMException.prototype, ErrorPrototype); webidl.configurePrototype(DOMException); |