mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 04:48:52 -05:00
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 ```
This commit is contained in:
parent
5ef225853c
commit
348287825c
1 changed files with 16 additions and 17 deletions
|
@ -15,7 +15,6 @@ const {
|
||||||
MapPrototypeSet,
|
MapPrototypeSet,
|
||||||
Uint8Array,
|
Uint8Array,
|
||||||
Uint32Array,
|
Uint32Array,
|
||||||
NumberPOSITIVE_INFINITY,
|
|
||||||
PromisePrototypeThen,
|
PromisePrototypeThen,
|
||||||
SafeArrayIterator,
|
SafeArrayIterator,
|
||||||
SafeMap,
|
SafeMap,
|
||||||
|
@ -190,7 +189,7 @@ function initializeTimer(
|
||||||
// 13. Run steps after a timeout given global, "setTimeout/setInterval",
|
// 13. Run steps after a timeout given global, "setTimeout/setInterval",
|
||||||
// timeout, completionStep, and id.
|
// timeout, completionStep, and id.
|
||||||
runAfterTimeout(
|
runAfterTimeout(
|
||||||
() => ArrayPrototypePush(timerTasks, task),
|
task,
|
||||||
timeout,
|
timeout,
|
||||||
timerInfo,
|
timerInfo,
|
||||||
);
|
);
|
||||||
|
@ -203,7 +202,7 @@ function initializeTimer(
|
||||||
/**
|
/**
|
||||||
* @typedef ScheduledTimer
|
* @typedef ScheduledTimer
|
||||||
* @property {number} millis
|
* @property {number} millis
|
||||||
* @property {() => void} cb
|
* @property { {action: () => void, nestingLevel: number}[] } task
|
||||||
* @property {boolean} resolved
|
* @property {boolean} resolved
|
||||||
* @property {ScheduledTimer | null} prev
|
* @property {ScheduledTimer | null} prev
|
||||||
* @property {ScheduledTimer | null} next
|
* @property {ScheduledTimer | null} next
|
||||||
|
@ -216,12 +215,12 @@ function initializeTimer(
|
||||||
const scheduledTimers = { head: null, tail: null };
|
const scheduledTimers = { head: null, tail: null };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {() => void} cb Will be run after the timeout, if it hasn't been
|
* @param { {action: () => void, nestingLevel: number}[] } task Will be run
|
||||||
* cancelled.
|
* after the timeout, if it hasn't been cancelled.
|
||||||
* @param {number} millis
|
* @param {number} millis
|
||||||
* @param {{ cancelRid: number, isRef: boolean, promiseId: number }} timerInfo
|
* @param {{ cancelRid: number, isRef: boolean, promiseId: number }} timerInfo
|
||||||
*/
|
*/
|
||||||
function runAfterTimeout(cb, millis, timerInfo) {
|
function runAfterTimeout(task, millis, timerInfo) {
|
||||||
const cancelRid = timerInfo.cancelRid;
|
const cancelRid = timerInfo.cancelRid;
|
||||||
let sleepPromise;
|
let sleepPromise;
|
||||||
// If this timeout is scheduled for 0ms it means we want it to run at the
|
// 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} */
|
/** @type {ScheduledTimer} */
|
||||||
const timerObject = {
|
const timerObject = {
|
||||||
millis,
|
millis,
|
||||||
cb,
|
|
||||||
resolved: false,
|
resolved: false,
|
||||||
prev: scheduledTimers.tail,
|
prev: scheduledTimers.tail,
|
||||||
next: null,
|
next: null,
|
||||||
|
@ -260,6 +258,10 @@ function runAfterTimeout(cb, millis, timerInfo) {
|
||||||
PromisePrototypeThen(
|
PromisePrototypeThen(
|
||||||
sleepPromise,
|
sleepPromise,
|
||||||
(cancelled) => {
|
(cancelled) => {
|
||||||
|
if (timerObject.resolved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// "op_void_async_deferred" returns null
|
// "op_void_async_deferred" returns null
|
||||||
if (cancelled !== null && !cancelled) {
|
if (cancelled !== null && !cancelled) {
|
||||||
// The timer was 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
|
// b) its timeout is lower than the lowest unresolved timeout found so
|
||||||
// far in the list.
|
// far in the list.
|
||||||
|
|
||||||
timerObject.resolved = true;
|
|
||||||
|
|
||||||
let lowestUnresolvedTimeout = NumberPOSITIVE_INFINITY;
|
|
||||||
|
|
||||||
let currentEntry = scheduledTimers.head;
|
let currentEntry = scheduledTimers.head;
|
||||||
while (currentEntry !== null) {
|
while (currentEntry !== null) {
|
||||||
if (currentEntry.millis < lowestUnresolvedTimeout) {
|
if (currentEntry.millis <= timerObject.millis) {
|
||||||
if (currentEntry.resolved) {
|
currentEntry.resolved = true;
|
||||||
currentEntry.cb();
|
ArrayPrototypePush(timerTasks, task);
|
||||||
removeFromScheduledTimers(currentEntry);
|
removeFromScheduledTimers(currentEntry);
|
||||||
} else {
|
|
||||||
lowestUnresolvedTimeout = currentEntry.millis;
|
if (currentEntry === timerObject) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue