diff options
Diffstat (limited to 'ext/node')
-rw-r--r-- | ext/node/polyfills/internal/stream_base_commons.ts | 4 | ||||
-rw-r--r-- | ext/node/polyfills/internal_binding/stream_wrap.ts | 30 |
2 files changed, 32 insertions, 2 deletions
diff --git a/ext/node/polyfills/internal/stream_base_commons.ts b/ext/node/polyfills/internal/stream_base_commons.ts index d7acf729d..01da0c5e3 100644 --- a/ext/node/polyfills/internal/stream_base_commons.ts +++ b/ext/node/polyfills/internal/stream_base_commons.ts @@ -253,7 +253,9 @@ export function onStreamRead( } } else { const offset = streamBaseState[kArrayBufferOffset]; - const buf = Buffer.from(arrayBuffer, offset, nread); + // Performance note: Pass ArrayBuffer to Buffer#from to avoid + // copy. + const buf = Buffer.from(arrayBuffer.buffer, offset, nread); result = stream.push(buf); } diff --git a/ext/node/polyfills/internal_binding/stream_wrap.ts b/ext/node/polyfills/internal_binding/stream_wrap.ts index 27870b20b..95f60fe95 100644 --- a/ext/node/polyfills/internal_binding/stream_wrap.ts +++ b/ext/node/polyfills/internal_binding/stream_wrap.ts @@ -40,6 +40,9 @@ import { } from "ext:deno_node/internal_binding/async_wrap.ts"; import { codeMap } from "ext:deno_node/internal_binding/uv.ts"; +const core = globalThis.Deno.core; +const { ops } = core; + interface Reader { read(p: Uint8Array): Promise<number | null>; } @@ -54,7 +57,7 @@ export interface Closer { type Ref = { ref(): void; unref(): void }; -enum StreamBaseStateFields { +const enum StreamBaseStateFields { kReadBytesOrError, kArrayBufferOffset, kBytesWritten, @@ -195,6 +198,31 @@ export class LibuvStreamWrap extends HandleWrap { chunks: Buffer[] | (string | Buffer)[], allBuffers: boolean, ): number { + const supportsWritev = this.provider === providerType.TCPSERVERWRAP; + // Fast case optimization: two chunks, and all buffers. + if (chunks.length === 2 && allBuffers && supportsWritev) { + // String chunks. + if (typeof chunks[0] === "string") chunks[0] = Buffer.from(chunks[0]); + if (typeof chunks[1] === "string") chunks[1] = Buffer.from(chunks[1]); + + ops.op_raw_write_vectored( + this[kStreamBaseField]!.rid, + chunks[0], + chunks[1], + ).then((nwritten) => { + try { + req.oncomplete(0); + } catch { + // swallow callback errors. + } + + streamBaseState[kBytesWritten] = nwritten; + this.bytesWritten += nwritten; + }); + + return 0; + } + const count = allBuffers ? chunks.length : chunks.length >> 1; const buffers: Buffer[] = new Array(count); |