diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-06-14 17:04:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-14 17:04:49 +0200 |
commit | 348287825cdefecdd6dda6ce5c8652fdfc69837c (patch) | |
tree | 223e124cc9b3a27fc879dbf5f487249a208f9804 /ext/web/02_timers.js | |
parent | 5ef225853c0f81ba0a7d1ce888ab3b2d283eae0a (diff) |
perf(web): optimize timer resolution (#19493)
Closes https://github.com/denoland/deno/issues/19348
This changes benchmark from the issue from:
```
deno run -A https://raw.githubusercontent.com/nats-io/nats.deno/deno-transport-changes/examples/bench.js --subject a --payload 3500 --pub --count 650000
pub 7,636 msgs/sec - [85.13 secs] ~ 25.49 MB/sec 85127.8765/85127.8765
```
to:
```
> ./target/release/deno run -A https://raw.githubusercontent.com/nats-io/nats.deno/deno-transport-changes/examples/bench.js --subject a --payload 3500 --pub --count 650000
pub 176,840 msgs/sec - [3.68 secs] ~ 590.27 MB/sec 3675.646833/3675.646833
> ./target/release/deno run -A https://raw.githubusercontent.com/nats-io/nats.deno/deno-transport-changes/examples/bench.js --subject a --payload 3500 --pub --count 650000
pub 174,589 msgs/sec - [3.72 secs] ~ 582.76 MB/sec 3723.01925/3723.01925
```
Diffstat (limited to 'ext/web/02_timers.js')
-rw-r--r-- | ext/web/02_timers.js | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js index 27e2e953d..cfabdeb98 100644 --- a/ext/web/02_timers.js +++ b/ext/web/02_timers.js @@ -15,7 +15,6 @@ const { MapPrototypeSet, Uint8Array, Uint32Array, - NumberPOSITIVE_INFINITY, PromisePrototypeThen, SafeArrayIterator, SafeMap, @@ -190,7 +189,7 @@ function initializeTimer( // 13. Run steps after a timeout given global, "setTimeout/setInterval", // timeout, completionStep, and id. runAfterTimeout( - () => ArrayPrototypePush(timerTasks, task), + task, timeout, timerInfo, ); @@ -203,7 +202,7 @@ function initializeTimer( /** * @typedef ScheduledTimer * @property {number} millis - * @property {() => void} cb + * @property { {action: () => void, nestingLevel: number}[] } task * @property {boolean} resolved * @property {ScheduledTimer | null} prev * @property {ScheduledTimer | null} next @@ -216,12 +215,12 @@ function initializeTimer( const scheduledTimers = { head: null, tail: null }; /** - * @param {() => void} cb Will be run after the timeout, if it hasn't been - * cancelled. + * @param { {action: () => void, nestingLevel: number}[] } task Will be run + * after the timeout, if it hasn't been cancelled. * @param {number} millis * @param {{ cancelRid: number, isRef: boolean, promiseId: number }} timerInfo */ -function runAfterTimeout(cb, millis, timerInfo) { +function runAfterTimeout(task, millis, timerInfo) { const cancelRid = timerInfo.cancelRid; let sleepPromise; // If this timeout is scheduled for 0ms it means we want it to run at the @@ -241,7 +240,6 @@ function runAfterTimeout(cb, millis, timerInfo) { /** @type {ScheduledTimer} */ const timerObject = { millis, - cb, resolved: false, prev: scheduledTimers.tail, next: null, @@ -260,6 +258,10 @@ function runAfterTimeout(cb, millis, timerInfo) { PromisePrototypeThen( sleepPromise, (cancelled) => { + if (timerObject.resolved) { + return; + } + // "op_void_async_deferred" returns null if (cancelled !== null && !cancelled) { // The timer was cancelled. @@ -280,18 +282,15 @@ function runAfterTimeout(cb, millis, timerInfo) { // b) its timeout is lower than the lowest unresolved timeout found so // far in the list. - timerObject.resolved = true; - - let lowestUnresolvedTimeout = NumberPOSITIVE_INFINITY; - let currentEntry = scheduledTimers.head; while (currentEntry !== null) { - if (currentEntry.millis < lowestUnresolvedTimeout) { - if (currentEntry.resolved) { - currentEntry.cb(); - removeFromScheduledTimers(currentEntry); - } else { - lowestUnresolvedTimeout = currentEntry.millis; + if (currentEntry.millis <= timerObject.millis) { + currentEntry.resolved = true; + ArrayPrototypePush(timerTasks, task); + removeFromScheduledTimers(currentEntry); + + if (currentEntry === timerObject) { + break; } } |