Skip to content

Commit 41c22e6

Browse files
authored
Improve TypedArray::to_vec performance by not zero-initializing buffer (#2650)
1 parent e104d16 commit 41c22e6

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

crates/js-sys/src/lib.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5090,11 +5090,23 @@ macro_rules! arrays {
50905090
)
50915091
}
50925092

5093-
fn raw_copy_to(&self, dst: &mut [$ty]) {
5093+
5094+
/// Copy the contents of this JS typed array into the destination
5095+
/// Rust pointer.
5096+
///
5097+
/// This function will efficiently copy the memory from a typed
5098+
/// array into this wasm module's own linear memory, initializing
5099+
/// the memory destination provided.
5100+
///
5101+
/// # Unsafety
5102+
///
5103+
/// This function requires `dst` to point to a buffer
5104+
/// large enough to fit this array's contents.
5105+
pub unsafe fn raw_copy_to_ptr(&self, dst: *mut $ty) {
50945106
let buf = wasm_bindgen::memory();
50955107
let mem = buf.unchecked_ref::<WebAssembly::Memory>();
50965108
let all_wasm_memory = $name::new(&mem.buffer());
5097-
let offset = dst.as_ptr() as usize / mem::size_of::<$ty>();
5109+
let offset = dst as usize / mem::size_of::<$ty>();
50985110
all_wasm_memory.set(self, offset as u32);
50995111
}
51005112

@@ -5111,7 +5123,7 @@ macro_rules! arrays {
51115123
/// different than the length of the provided `dst` array.
51125124
pub fn copy_to(&self, dst: &mut [$ty]) {
51135125
assert_eq!(self.length() as usize, dst.len());
5114-
self.raw_copy_to(dst);
5126+
unsafe { self.raw_copy_to_ptr(dst.as_mut_ptr()); }
51155127
}
51165128

51175129
/// Copy the contents of the source Rust slice into this
@@ -5132,8 +5144,11 @@ macro_rules! arrays {
51325144

51335145
/// Efficiently copies the contents of this JS typed array into a new Vec.
51345146
pub fn to_vec(&self) -> Vec<$ty> {
5135-
let mut output = vec![$ty::default(); self.length() as usize];
5136-
self.raw_copy_to(&mut output);
5147+
let mut output = Vec::with_capacity(self.length() as usize);
5148+
unsafe {
5149+
self.raw_copy_to_ptr(output.as_mut_ptr());
5150+
output.set_len(self.length() as usize);
5151+
}
51375152
output
51385153
}
51395154
}

0 commit comments

Comments
 (0)