Skip to content
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

Speed up transfer of outputs to notebook webviews #178719

Merged
merged 1 commit into from Mar 30, 2023

Conversation

mjbvz
Copy link
Contributor

@mjbvz mjbvz commented Mar 30, 2023

For microsoft/vscode-jupyter#11031

The VS Buffer for the output items has a short byte length but a very large backing buffer (Uint8Array which is actually a Buffer)

When sending outputs to the webview, we ended up transfering the huge backing buffer instead of the much smaller actual data

We can fix this by creating a Uint8Array copy of the data and then transfering it to the webview

For microsoft/vscode-jupyter#11031

The VS Buffer for the output items has a short byte length but a very large backing buffer (`Uint8Array` which is actually a `Buffer`)

When sending outputs to the webview, we ended up transfering the huge backing buffer instead of the much smaller actual data

We can fix this by creating a Uint8Array copy of the data and then transfering it to the webview
@mjbvz mjbvz requested a review from rebornix March 30, 2023 20:00
@mjbvz mjbvz self-assigned this Mar 30, 2023
@VSCodeTriageBot VSCodeTriageBot added this to the April 2023 milestone Mar 30, 2023
// which improves IPC performance and therefore should be used. However, it does
// means that the bytes cannot be used here anymore

// Copy the underlying buffer so we only send over the data we need
Copy link
Contributor Author

@mjbvz mjbvz Mar 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrieken @alexdima In this instance, first.data.buffer is a Buffer which looks like a Uint8Array. This Buffer is much, much larger than the VSBuffer for first.data

Is there a way to avoid this size mismatch? I suspect it's an optimization to reduce the number of memory allocations

@rebornix
Copy link
Member

When we send notebook model dto from EH to Renderer, we merged all buffers into one

private static _serializeReplyOKJSONWithBuffers(req: number, res: string, buffers: readonly VSBuffer[]): VSBuffer {
const resBuff = VSBuffer.fromString(res);
let len = 0;
len += MessageBuffer.sizeUInt32; // buffer count
len += MessageBuffer.sizeLongString(resBuff);
for (const buffer of buffers) {
len += MessageBuffer.sizeVSBuffer(buffer);
}
const result = MessageBuffer.alloc(MessageType.ReplyOKJSONWithBuffers, req, len);
result.writeUInt32(buffers.length);
result.writeLongString(resBuff);
for (const buffer of buffers) {
result.writeBuffer(buffer);
}
return result.buffer;
}

I think that's how we end up with multiple buffers sharing the same ArrayBuffer in the Renderer. And then when we send them to Webview, we create a copy of the ArrayBuffer store for every buffer.

@mjbvz
Copy link
Contributor Author

mjbvz commented Mar 30, 2023

Thanks @rebornix. This may be the best fix then. Longer term, we could explore using a SharedArrayBuffer to transfer the data without the extra copies

@rebornix
Copy link
Member

I'll merge this first to ensure users don't have OOM with images. We should look into this and see if we can avoid the duplication of buffers.

@rebornix rebornix merged commit 9fd77b4 into microsoft:main Mar 30, 2023
7 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators May 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants