1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

perf(ext/event): optimize addEventListener options converter (#20203)

This PR optimizes `addEventListener` by replacing
`webidl.createDictionaryConverter("AddEventListenerOptions", ...)` with
a custom options parsing function to avoid the overhead of `webidl`
methods

**this PR**

```
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
---------------------------------------------------------------------------------------------------- -----------------------------
addEventListener options converter (undefined)       4.87 ns/iter 205,248,660.8     (4.7 ns … 13.18 ns)   4.91 ns    5.4 ns    5.6 ns
addEventListener options converter (signal)         13.02 ns/iter  76,782,031.2   (11.74 ns … 18.84 ns)  13.08 ns  16.22 ns  16.57 ns
```

**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
---------------------------------------------------------------------------------------------------- -----------------------------
addEventListener options converter (undefined)     108.36 ns/iter   9,228,688.6  (103.5 ns … 129.88 ns) 109.69 ns 115.61 ns 125.28 ns
addEventListener options converter (signal)        134.03 ns/iter   7,460,878.1 (129.14 ns … 144.54 ns) 135.68 ns 141.13 ns  144.1 ns
```

```js
const tg = new EventTarget();
const signal = new AbortController().signal;

Deno.bench("addEventListener options converter (undefined)", () => {
  tg.addEventListener("foo", null); // null callback to only bench options converter
});

Deno.bench("addEventListener options converter (signal)", () => {
  tg.addEventListener("foo", null, { signal });
});
```

Towards https://github.com/denoland/deno/issues/20167
This commit is contained in:
Marcos Casagrande 2023-08-20 11:30:57 +02:00 committed by Divy Srivastava
parent 1631ffa332
commit 627499177f

View file

@ -896,45 +896,29 @@ function getDefaultTargetData() {
};
}
// This is lazy loaded because there is a circular dependency with AbortSignal.
let addEventListenerOptionsConverter;
function addEventListenerOptionsConverter(V, prefix) {
if (webidl.type(V) !== "Object") {
return { capture: !!V, once: false, passive: false };
}
function lazyAddEventListenerOptionsConverter() {
addEventListenerOptionsConverter ??= webidl.createDictionaryConverter(
"AddEventListenerOptions",
[
{
key: "capture",
defaultValue: false,
converter: webidl.converters.boolean,
},
{
key: "passive",
defaultValue: false,
converter: webidl.converters.boolean,
},
{
key: "once",
defaultValue: false,
converter: webidl.converters.boolean,
},
{
key: "signal",
converter: webidl.converters.AbortSignal,
},
],
const options = {
capture: !!V.capture,
once: !!V.once,
passive: !!V.passive,
};
const signal = V.signal;
if (signal !== undefined) {
options.signal = webidl.converters.AbortSignal(
signal,
prefix,
"'signal' of 'AddEventListenerOptions' (Argument 3)",
);
}
webidl.converters.AddEventListenerOptions = (V, prefix, context, opts) => {
if (webidl.type(V) !== "Object" || V === null) {
V = { capture: Boolean(V) };
return options;
}
lazyAddEventListenerOptionsConverter();
return addEventListenerOptionsConverter(V, prefix, context, opts);
};
class EventTarget {
constructor() {
this[eventTargetData] = getDefaultTargetData();
@ -952,11 +936,7 @@ class EventTarget {
webidl.requiredArguments(arguments.length, 2, prefix);
options = webidl.converters.AddEventListenerOptions(
options,
prefix,
"Argument 3",
);
options = addEventListenerOptionsConverter(options, prefix);
if (callback === null) {
return;