summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorMarcos Casagrande <marcoscvp90@gmail.com>2022-11-15 14:06:52 +0100
committerGitHub <noreply@github.com>2022-11-15 14:06:52 +0100
commit0832ba1deb9eb43c0a724112eed3f2d7d9a0819b (patch)
tree8dd6b7bc5968635c88d92830d0b8e46adf7f7dcf /ext
parentf2bf40d157879cf05a9334d9a4676562bdf1b1c1 (diff)
perf(runtime/spawn): collect output using `op_read_all` (#16596)
**This patch** ``` benchmark time (avg) (min … max) p75 p99 p995 ------------------------------------------------- ----------------------------- echo deno 23.99 ms/iter (22.51 ms … 33.61 ms) 23.97 ms 33.61 ms 33.61 ms cat 16kb 24.27 ms/iter (22.5 ms … 35.21 ms) 24.2 ms 35.21 ms 35.21 ms cat 1mb 25.88 ms/iter (25.04 ms … 30.28 ms) 26.12 ms 30.28 ms 30.28 ms cat 15mb 38.41 ms/iter (35.7 ms … 50 ms) 38.31 ms 50 ms 50 ms ``` **main** ``` benchmark time (avg) (min … max) p75 p99 p995 ------------------------------------------------- ----------------------------- echo deno 35.66 ms/iter (34.53 ms … 41.84 ms) 35.79 ms 41.84 ms 41.84 ms cat 16kb 35.99 ms/iter (34.52 ms … 44.94 ms) 36.05 ms 44.94 ms 44.94 ms cat 1mb 38.68 ms/iter (36.67 ms … 50.44 ms) 37.95 ms 50.44 ms 50.44 ms cat 15mb 48.4 ms/iter (46.19 ms … 58.41 ms) 49.16 ms 58.41 ms 58.41 ms ```
Diffstat (limited to 'ext')
-rw-r--r--ext/web/06_streams.js30
1 files changed, 26 insertions, 4 deletions
diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js
index 0b9e00483..d51556a37 100644
--- a/ext/web/06_streams.js
+++ b/ext/web/06_streams.js
@@ -730,6 +730,7 @@
const stream = webidl.createBranded(ReadableStream);
stream[promiseIdSymbol] = undefined;
stream[_isUnref] = false;
+ stream[_resourceBackingUnrefable] = { rid, autoClose: true };
const underlyingSource = {
type: "bytes",
async pull(controller) {
@@ -767,8 +768,14 @@
return stream;
}
+ function readableStreamIsUnrefable(stream) {
+ return _isUnref in stream;
+ }
+
function readableStreamForRidUnrefableRef(stream) {
- if (!(_isUnref in stream)) throw new TypeError("Not an unrefable stream");
+ if (!readableStreamIsUnrefable(stream)) {
+ throw new TypeError("Not an unrefable stream");
+ }
stream[_isUnref] = false;
if (stream[promiseIdSymbol] !== undefined) {
core.refOp(stream[promiseIdSymbol]);
@@ -776,7 +783,9 @@
}
function readableStreamForRidUnrefableUnref(stream) {
- if (!(_isUnref in stream)) throw new TypeError("Not an unrefable stream");
+ if (!readableStreamIsUnrefable(stream)) {
+ throw new TypeError("Not an unrefable stream");
+ }
stream[_isUnref] = true;
if (stream[promiseIdSymbol] !== undefined) {
core.unrefOp(stream[promiseIdSymbol]);
@@ -787,15 +796,25 @@
return stream[_resourceBacking];
}
+ function getReadableStreamResourceBackingUnrefable(stream) {
+ return stream[_resourceBackingUnrefable];
+ }
+
async function readableStreamCollectIntoUint8Array(stream) {
- const resourceBacking = getReadableStreamResourceBacking(stream);
+ const resourceBacking = getReadableStreamResourceBacking(stream) ||
+ getReadableStreamResourceBackingUnrefable(stream);
const reader = acquireReadableStreamDefaultReader(stream);
if (resourceBacking) {
// fast path, read whole body in a single op call
try {
readableStreamDisturb(stream);
- const buf = await core.opAsync("op_read_all", resourceBacking.rid);
+ const promise = core.opAsync("op_read_all", resourceBacking.rid);
+ if (readableStreamIsUnrefable(stream)) {
+ const promiseId = stream[promiseIdSymbol] = promise[promiseIdSymbol];
+ if (stream[_isUnref]) core.unrefOp(promiseId);
+ }
+ const buf = await promise;
readableStreamThrowIfErrored(stream);
readableStreamClose(stream);
return buf;
@@ -4585,6 +4604,9 @@
}
const _resourceBacking = Symbol("[[resourceBacking]]");
+ // This distinction exists to prevent unrefable streams being used in
+ // regular fast streams that are unaware of refability
+ const _resourceBackingUnrefable = Symbol("[[resourceBackingUnrefable]]");
/** @template R */
class ReadableStream {
/** @type {ReadableStreamDefaultController | ReadableByteStreamController} */