summaryrefslogtreecommitdiff
path: root/ext/web
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2024-07-30 05:39:55 -0700
committerGitHub <noreply@github.com>2024-07-30 18:09:55 +0530
commit1ba88a7892fa1b0d7cf229b0cd5709575901ebd0 (patch)
treeabb158d0bc7a927c7c387bed25aae9faf7e0a7e4 /ext/web
parentc6ecf70a0963ce5cac67af97c55aa360a1d25c4b (diff)
perf(ext/node): improve `Buffer` from string performance (#24567)
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 ```
Diffstat (limited to 'ext/web')
-rw-r--r--ext/web/lib.rs39
1 files changed, 35 insertions, 4 deletions
diff --git a/ext/web/lib.rs b/ext/web/lib.rs
index 89f1197e7..c8badbf8a 100644
--- a/ext/web/lib.rs
+++ b/ext/web/lib.rs
@@ -16,7 +16,6 @@ use deno_core::ByteString;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
-use deno_core::ToJsBuffer;
use deno_core::U16String;
use encoding_rs::CoderResult;
@@ -62,6 +61,7 @@ deno_core::extension!(deno_web,
parameters = [P: TimersPermission],
ops = [
op_base64_decode,
+ op_base64_write,
op_base64_encode,
op_base64_atob,
op_base64_btoa,
@@ -130,12 +130,43 @@ deno_core::extension!(deno_web,
);
#[op2]
-#[serde]
-fn op_base64_decode(#[string] input: String) -> Result<ToJsBuffer, AnyError> {
+#[buffer]
+fn op_base64_decode(#[string] input: String) -> Result<Vec<u8>, AnyError> {
let mut s = input.into_bytes();
let decoded_len = forgiving_base64_decode_inplace(&mut s)?;
s.truncate(decoded_len);
- Ok(s.into())
+ Ok(s)
+}
+
+#[op2(fast)]
+#[smi]
+fn op_base64_write(
+ #[string] input: String,
+ #[buffer] buffer: &mut [u8],
+ #[smi] start: u32,
+ #[smi] max_len: u32,
+) -> Result<u32, AnyError> {
+ let tsb_len = buffer.len() as u32;
+
+ if start > tsb_len {
+ return Err(type_error("Offset is out of bounds"));
+ }
+
+ let max_len = std::cmp::min(max_len, tsb_len - start) as usize;
+ let start = start as usize;
+
+ if max_len == 0 {
+ return Ok(0);
+ }
+
+ let mut s = input.into_bytes();
+ let decoded_len = forgiving_base64_decode_inplace(&mut s)?;
+
+ let max_len = std::cmp::min(max_len, decoded_len);
+
+ buffer[start..start + max_len].copy_from_slice(&s[..max_len]);
+
+ Ok(max_len as u32)
}
#[op2]