perf(ext/node): optimize net streams (#19678)

~4.5x improvement in `npm:ws` echo benchmark:

```
$ ./load_test 10 0.0.0.0 8080 0 0
Using message size of 20 bytes
Running benchmark now...
Msg/sec: 101083.750000
Msg/sec: 103606.000000
^C

$ ./load_test 10 0.0.0.0 8080 0 0
Using message size of 20 bytes
Running benchmark now...
Msg/sec: 24906.750000
Msg/sec: 28478.000000
^C
```
This commit is contained in:
Divy Srivastava 2023-07-05 22:45:10 +05:30 committed by GitHub
parent 2e7bcb422d
commit 57fae55d82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 2 deletions

View file

@ -9,7 +9,10 @@ use deno_core::error::AnyError;
use deno_core::located_script_name; use deno_core::located_script_name;
use deno_core::op; use deno_core::op;
use deno_core::serde_json; use deno_core::serde_json;
use deno_core::serde_v8;
use deno_core::url::Url; use deno_core::url::Url;
#[allow(unused_imports)]
use deno_core::v8;
use deno_core::JsRuntime; use deno_core::JsRuntime;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_fs::sync::MaybeSend; use deno_fs::sync::MaybeSend;
@ -130,6 +133,11 @@ fn op_node_build_os() -> String {
.to_string() .to_string()
} }
#[op(fast)]
fn op_is_any_arraybuffer(value: serde_v8::Value) -> bool {
value.v8_value.is_array_buffer() || value.v8_value.is_shared_array_buffer()
}
deno_core::extension!(deno_node, deno_core::extension!(deno_node,
deps = [ deno_io, deno_fs ], deps = [ deno_io, deno_fs ],
parameters = [P: NodePermissions], parameters = [P: NodePermissions],
@ -224,6 +232,7 @@ deno_core::extension!(deno_node,
ops::zlib::brotli::op_brotli_decompress_stream_end, ops::zlib::brotli::op_brotli_decompress_stream_end,
ops::http::op_node_http_request<P>, ops::http::op_node_http_request<P>,
op_node_build_os, op_node_build_os,
op_is_any_arraybuffer,
ops::require::op_require_init_paths, ops::require::op_require_init_paths,
ops::require::op_require_node_module_paths<P>, ops::require::op_require_node_module_paths<P>,
ops::require::op_require_proxy_path, ops::require::op_require_proxy_path,

View file

@ -279,7 +279,7 @@ export class LibuvStreamWrap extends HandleWrap {
/** Internal method for reading from the attached stream. */ /** Internal method for reading from the attached stream. */
async #read() { async #read() {
let buf = new Uint8Array(SUGGESTED_SIZE); let buf = BUF;
let nread: number | null; let nread: number | null;
try { try {
@ -375,3 +375,5 @@ export class LibuvStreamWrap extends HandleWrap {
return; return;
} }
} }
const BUF = new Uint8Array(SUGGESTED_SIZE);

View file

@ -25,6 +25,7 @@
// deno-lint-ignore-file prefer-primordials // deno-lint-ignore-file prefer-primordials
const { core } = globalThis.__bootstrap; const { core } = globalThis.__bootstrap;
const { ops } = core;
// https://tc39.es/ecma262/#sec-object.prototype.tostring // https://tc39.es/ecma262/#sec-object.prototype.tostring
const _toString = Object.prototype.toString; const _toString = Object.prototype.toString;
@ -89,7 +90,7 @@ function isObjectLike(
export function isAnyArrayBuffer( export function isAnyArrayBuffer(
value: unknown, value: unknown,
): value is ArrayBuffer | SharedArrayBuffer { ): value is ArrayBuffer | SharedArrayBuffer {
return isArrayBuffer(value) || isSharedArrayBuffer(value); return ops.op_is_any_arraybuffer(value);
} }
export function isArgumentsObject(value: unknown): value is IArguments { export function isArgumentsObject(value: unknown): value is IArguments {