Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(web): optimize encodeInto() #15922

Merged
merged 10 commits into from
Sep 17, 2022
Merged

Conversation

littledivy
Copy link
Member

@littledivy littledivy commented Sep 16, 2022

Towards #15895

5.4x faster encodeInto()

# This patch
target/release/deno run -A --unstable cli/bench/encode_into.js
time 78 ms rate 12820512
time 66 ms rate 15151515
time 65 ms rate 15384615
time 66 ms rate 15151515
# main
deno run -A --unstable cli/bench/encode_into.js
time 362 ms rate 2762430
time 340 ms rate 2941176
time 340 ms rate 2941176
time 339 ms rate 2949852

ext/web/lib.rs Outdated Show resolved Hide resolved
ext/web/lib.rs Outdated Show resolved Hide resolved
@ghost
Copy link

ghost commented Sep 16, 2022

Would this same optimisation be applicable to encode() - the difference being who allocates the return Uint8Array?

ext/web/lib.rs Outdated Show resolved Hide resolved
ext/web/lib.rs Outdated Show resolved Hide resolved
@littledivy
Copy link
Member Author

We are passing 100% of encodeInto WPT now! (SABs are allowed in the op now)

@littledivy littledivy marked this pull request as ready for review September 16, 2022 15:48
ext/web/lib.rs Show resolved Hide resolved
ext/web/lib.rs Outdated
Comment on lines 328 to 331
// SAFETY: `out_buf` is guaranteed to be large enough to hold result.
let out_buf: &mut [u32] = unsafe {
std::slice::from_raw_parts_mut(out_buf.as_mut_ptr() as *mut u32, 2)
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand what guarantees alignment. Can you explain?

Note that getting the alignment wrong can lead to miscompiles, even on x86_64.

Copy link

@ghost ghost Sep 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In JS, ArrayBuffers with a length ≥ the necessary alignment of type T, are usable as that type.

Upon second thought though, as this accepts TypedArrays and turns them into &mut [u8], then it's still unsound, as one may pass new Uint8Array(5).subarray(1), which has a byteOffset that isn't aligned to a u32 boundary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yikes, lemme add &mut [u32] support to #[ops] to directly deal with Uint32Array

@billywhizz
Copy link
Contributor

i benchmarked this change against current implementation: #15895 (comment)

ext/web/lib.rs Outdated Show resolved Hide resolved
ops/lib.rs Show resolved Hide resolved
ops/lib.rs Outdated Show resolved Hide resolved
ops/lib.rs Outdated Show resolved Hide resolved
@@ -991,94 +991,8 @@
"api-replacement-encodings.any.worker.html": true,
"api-surrogates-utf8.any.html": true,
"api-surrogates-utf8.any.worker.html": true,
"encodeInto.any.html": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

@littledivy littledivy merged commit 5fe660e into denoland:main Sep 17, 2022
dsherret pushed a commit that referenced this pull request Sep 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants