diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-07-07 22:17:08 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-07 22:17:08 +0530 |
commit | e4870d84be19f4ea768933522eff437f64963730 (patch) | |
tree | 789e83bc1d67754b917874b8f92d4a1227644930 /ext/node/polyfills/internal_binding | |
parent | 7d022ad11a74710ce46e4ab9f4e57635cae3ed2e (diff) |
perf(ext/node): native vectored write for server streams (#19752)
```
# main
$ ./load_test 10 0.0.0.0 8080 0 0
Using message size of 20 bytes
Running benchmark now...
Msg/sec: 106182.250000
Msg/sec: 110279.750000
^C
# this PR
$ ./load_test 10 0.0.0.0 8080 0 0
Using message size of 20 bytes
Running benchmark now...
Msg/sec: 131632.250000
Msg/sec: 134754.250000
^C
```
Diffstat (limited to 'ext/node/polyfills/internal_binding')
-rw-r--r-- | ext/node/polyfills/internal_binding/stream_wrap.ts | 30 |
1 files changed, 29 insertions, 1 deletions
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); |