From 1ba88a7892fa1b0d7cf229b0cd5709575901ebd0 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Tue, 30 Jul 2024 05:39:55 -0700 Subject: perf(ext/node): improve `Buffer` from string performance (#24567) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/denoland/deno/issues/24323 - Use a Buffer pool for `fromString` - Implement fast call base64 writes - Direct from string `create` method for each encoding op ``` $ deno bench -A bench.mjs # 1.45.1+fee4d3a cpu: Apple M1 Pro runtime: deno 1.45.1+fee4d3a (aarch64-apple-darwin) benchmark time (avg) (min … max) p75 p99 p999 ----------------------------------------------------------- ----------------------------- Buffer.from base64 550 ns/iter (490 ns … 1'265 ns) 572 ns 606 ns 1'265 ns Buffer#write base64 285 ns/iter (259 ns … 371 ns) 307 ns 347 ns 360 ns $ ~/gh/deno/target/release/deno bench -A bench.mjs # this PR cpu: Apple M1 Pro runtime: deno dev (aarch64-apple-darwin) benchmark time (avg) (min … max) p75 p99 p999 ----------------------------------------------------------- ----------------------------- Buffer.from base64 151 ns/iter (145 ns … 770 ns) 148 ns 184 ns 648 ns Buffer#write base64 62.58 ns/iter (60.79 ns … 157 ns) 61.65 ns 75.79 ns 141 ns $ node bench.mjs # v22.4.0 cpu: Apple M1 Pro runtime: node v22.4.0 (arm64-darwin) benchmark time (avg) (min … max) p75 p99 p999 ----------------------------------------------------------- ----------------------------- Buffer.from base64 163 ns/iter (96.92 ns … 375 ns) 99.45 ns 127 ns 220 ns Buffer#write base64 75.48 ns/iter (74.97 ns … 134 ns) 75.17 ns 81.83 ns 96.84 ns ``` --- ext/node/polyfills/string_decoder.ts | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'ext/node/polyfills/string_decoder.ts') diff --git a/ext/node/polyfills/string_decoder.ts b/ext/node/polyfills/string_decoder.ts index 4a49c2e3e..19aff8124 100644 --- a/ext/node/polyfills/string_decoder.ts +++ b/ext/node/polyfills/string_decoder.ts @@ -39,10 +39,15 @@ const { Symbol, MathMin, DataViewPrototypeGetBuffer, + DataViewPrototypeGetByteLength, + DataViewPrototypeGetByteOffset, ObjectPrototypeIsPrototypeOf, String, TypedArrayPrototypeGetBuffer, + TypedArrayPrototypeGetByteLength, + TypedArrayPrototypeGetByteOffset, StringPrototypeToLowerCase, + Uint8Array, } = primordials; const { isTypedArray } = core; @@ -83,11 +88,21 @@ function normalizeBuffer(buf: Buffer) { } if (isBufferType(buf)) { return buf; + } else if (isTypedArray(buf)) { + return Buffer.from( + new Uint8Array( + TypedArrayPrototypeGetBuffer(buf), + TypedArrayPrototypeGetByteOffset(buf), + TypedArrayPrototypeGetByteLength(buf), + ), + ); } else { return Buffer.from( - isTypedArray(buf) - ? TypedArrayPrototypeGetBuffer(buf) - : DataViewPrototypeGetBuffer(buf), + new Uint8Array( + DataViewPrototypeGetBuffer(buf), + DataViewPrototypeGetByteOffset(buf), + DataViewPrototypeGetByteLength(buf), + ), ); } } -- cgit v1.2.3