-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance of WHATWG ReadableStream.read() #82
Comments
This could also probably impact fetch perf too! |
Removing primordials like |
Getting rid of diff --git a/lib/internal/webstreams/readablestream.js b/lib/internal/webstreams/readablestream.js
index 0b8b8ac1ef..9797a04c2c 100644
--- a/lib/internal/webstreams/readablestream.js
+++ b/lib/internal/webstreams/readablestream.js
@@ -46,6 +46,7 @@ const {
const {
isArrayBufferView,
isDataView,
+ isPromise,
} = require('internal/util/types');
const {
@@ -2249,16 +2250,29 @@ function readableStreamDefaultControllerCallPullIfNeeded(controller) {
}
assert(!controller[kState].pullAgain);
controller[kState].pulling = true;
- PromisePrototypeThen(
- ensureIsPromise(controller[kState].pullAlgorithm, controller),
- () => {
- controller[kState].pulling = false;
- if (controller[kState].pullAgain) {
- controller[kState].pullAgain = false;
- readableStreamDefaultControllerCallPullIfNeeded(controller);
- }
- },
- (error) => readableStreamDefaultControllerError(controller, error));
+
+ function onPullResolve() {
+ controller[kState].pulling = false;
+ if (controller[kState].pullAgain) {
+ controller[kState].pullAgain = false;
+ readableStreamDefaultControllerCallPullIfNeeded(controller);
+ }
+ }
+
+ try {
+ const value = FunctionPrototypeCall(controller[kState].pullAlgorithm, controller);
+
+ if (isPromise(value)) {
+ PromisePrototypeThen(
+ value,
+ onPullResolve,
+ (error) => readableStreamDefaultControllerError(controller, error));
+ } else {
+ onPullResolve();
+ }
+ } catch (error) {
+ return readableStreamDefaultControllerError(controller, error);
+ }
}
function readableStreamDefaultControllerClearAlgorithms(controller) { benchmark:
|
Does Deno and Bun implement webstreams in their native languages or in javascript? |
How is the performance difference? @debadree25 |
I remembered seeing around 6-7% but have to check again |
Will investigate |
Deno implements it in javascript, https://github.com/denoland/deno/blob/fc6ba92024d76d44349c36dcedd13994116db45b/ext/web/06_streams.js#L5066; they do use native functions for detaching arraybuffers/checking if an arraybuffer is detached. Bun I assume is using webkit's streams implementation, which would be native. Deno isn't using any array methods in its implementation, So they do eventually push it to an array, but only when the queue is empty (see: https://github.com/denoland/deno/blob/fc6ba92024d76d44349c36dcedd13994116db45b/ext/web/06_streams.js#L5648) |
I've done some exploring on creating The Therefore, to optimize the creation of Since I don't know much about C++, I'll stop now and take a look at |
@H4ad For more info about |
re: |
So it turns out Refs: |
is there reflect construct anywhere in the path of read()? Today i tried a few experiments with this
|
Refs: nodejs/performance#82 PR-URL: #49622 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Refs: nodejs/performance#82 PR-URL: #49622 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Hi @debadree25, is there a PR we can check? I might be able to spend some time soon; just have a few pending on other projects but happy to support 🙂 |
Dont really have any specific PR here mostly explored stuff locally @metcoder95 |
Maybe we can open one and start from there; we can iterate and see what do we found. Also we might get attention from more people over the reviews 👍 |
made a small attempt in nodejs/node#50340 Looking at the CPU profile of this simple script: const rs = new ReadableStream({
pull: function(controller) {
controller.enqueue('a');
},
});
const reader = rs.getReader();
let x = null;
const start = Date.now();
for (let i = 0; i < 1e6; i++) {
const { value } = await reader.read();
x = value;
}
console.log(Date.now() - start);
console.assert(x); ensureIsPromise is an interesting one need to find ways to improving it without breaking wpts. |
Refs: nodejs/performance#82 PR-URL: nodejs#49622 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
optimizations here can be tricky without impacting the observable spec-defined behavior of the streams. I recommend proceeding with caution. Also, while it is possible to implement this at the c++ level it is incredibly complicated to do so correctly given how difficult it is to work with V8's C++ level Promise API. I've documented some thoughts on general high-level optimizations that may be possible here: #134 |
The performance of ReadableStream.read() seems to be lacking behind other runtimes and probably can be improved
Ref: anonrig/node-benchmarks#3 (comment)
The text was updated successfully, but these errors were encountered: