Live data from Hacker News

Breaking the WASM/JS communication performance barrier

github.com

11–20 of 34 posts

Re: Breaking the WASM/JS communication performance barrier

#11

It's great that the rust community are finding ways to improve the performance of decoding strings from WASM to js, it's one of the major performance holes you hit when using WASM. The issue comes down to the fact that even if your WASM code can return a utf16 buffer, to use it as a string in JS code the engine needs to make a copy at some point. The TextDecoder api does a first good job of making this efficient, ens…

The JS string built-ins proposal for WebAssembly:

https://github.com/WebAssembly/js-string-builtins/blob/main/...

Re: Breaking the WASM/JS communication performance barrier

#12
post #11

It's great that the rust community are finding ways to improve the performance of decoding strings from WASM to js, it's one of the major performance holes you hit when using WASM. The issue comes down to the fact that even if your WASM code can return a utf16 buffer, to use it as a string in JS code the engine needs to make a copy at some point. The TextDecoder api does a first good job of making this efficient, ens…

The JS string built-ins proposal for WebAssembly: https://github.com/WebAssembly/js-string-builtins/blob/main/...

Personally I feel this is backwards - I don't want access to js literals and objects from WASM, I just want a way to wrap an arbitrary array buffer that contains a utf16 string as a js string.

It keeps WASM simple and provides a thin layer as an optimisation.

Re: Breaking the WASM/JS communication performance barrier

#13
post #11

Earlier quoted context omitted.

The JS string built-ins proposal for WebAssembly: https://github.com/WebAssembly/js-string-builtins/blob/main/...

Personally I feel this is backwards - I don't want access to js literals and objects from WASM, I just want a way to wrap an arbitrary array buffer that contains a utf16 string as a js string. It keeps WASM simple and provides a thin layer as an optimisation.

[deleted]

Re: Breaking the WASM/JS communication performance barrier

#14
post #11

Earlier quoted context omitted.

The JS string built-ins proposal for WebAssembly: https://github.com/WebAssembly/js-string-builtins/blob/main/...

Personally I feel this is backwards - I don't want access to js literals and objects from WASM, I just want a way to wrap an arbitrary array buffer that contains a utf16 string as a js string. It keeps WASM simple and provides a thin layer as an optimisation.

> It keeps WASM simple

At the cost of complicating JS string implementations, probably to the point of undoing the benefits.

Currently JS strings are immutable objects, allowing for all kinds of optimization tricks (interning, ropes, etc.). Having one string represented by a mutable arraybuffer messes with that.

There's probably also security concerns with allowing mutable access to string internals inside the JS engine side.

So the simple-appearing solution you suggested would be rejected all major browser vendors who back the various WASM and JS engines.

Access to constant JS strings without any form of mutability is the only realistic option for accessing JS strings. And creating constant strings is the only one for sending them back.

Re: Breaking the WASM/JS communication performance barrier

#15
> Wasm-bindgen calls TextDecoder.decode for every string. Sledgehammer only calls TextEncoder.decode once per batch.

So they decode one long concatenated string and then on the JS side split it into substrings? I wonder if that messes with the GC on the JS side of things.

Re: Breaking the WASM/JS communication performance barrier

#16

Earlier quoted context omitted.

Personally I feel this is backwards - I don't want access to js literals and objects from WASM, I just want a way to wrap an arbitrary array buffer that contains a utf16 string as a js string. It keeps WASM simple and provides a thin layer as an optimisation.

> It keeps WASM simple At the cost of complicating JS string implementations, probably to the point of undoing the benefits. Currently JS strings are immutable objects, allowing for all kinds of optimization tricks (interning, ropes, etc.). Having one string represented by a mutable arraybuffer messes with that. There's probably also security concerns with allowing mutable access to string internals inside the JS eng…

[deleted]

Re: Breaking the WASM/JS communication performance barrier

#17
I think there is a ton of room left on the table here for innovation.

Context: as far as I know Electron is still the king if you want to do (unsafe but performant) "IPC/RPC" between native and a webview.

All of the other options that exist in other languages (Deno, Rust, you name it) do the same "stringified JSON back and forth" which really isn't great for performance in my opinion.

It'd be cool if (obviously in a sandboxed or secure way) you could opt in to something albeit a bit reckless, but some way to provide native methods for the WASM part of V8 and its WebView (thinking Electron-esque here) to call.

Re: Breaking the WASM/JS communication performance barrier

#18

I think there is a ton of room left on the table here for innovation. Context: as far as I know Electron is still the king if you want to do (unsafe but performant) "IPC/RPC" between native and a webview. All of the other options that exist in other languages (Deno, Rust, you name it) do the same "stringified JSON back and forth" which really isn't great for performance in my opinion. It'd be cool if (obviously in a…

I'm not sure if I'm understanding you correctly, but vanilla wasm ipc works by sharing linear memory, where it's up to the implementation to choose the data encoding (arrow/proto/whatever). In the case of wasm-bindgen's dom manipulation api, the implementation serialises individual commands and sends them over the boundary, with any string params for each command being deserialised individually, and this project improves on that by batching them all into one big string thus reducing the deserialisation overhead. However, the string encoding is specific to that use case - it's not a general wasm ipc mechanism.

VSCode IPC is kinda similar as it's designed to facilitate comms over an enforced process isolation barrier to protect the main thread from slow extensions etc. but it's actually IPC there (as in, there are multiple processes at the os level). The wasm/js stuff is handled within the same v8 context - it's not actually ipc.

(Happy to be corrected here, but this is my understanding)

Re: Breaking the WASM/JS communication performance barrier

#19

> Wasm-bindgen calls TextDecoder.decode for every string. Sledgehammer only calls TextEncoder.decode once per batch. So they decode one long concatenated string and then on the JS side split it into substrings? I wonder if that messes with the GC on the JS side of things.

How would splitting it into substrings be different from decoding individual strings from an allocation/gc perspective? If anything I'd assume splitting a substring was more efficient - i expect there's a ton of optimisations in js for sliced strings or whatever as it's been around for ages.

Re: Breaking the WASM/JS communication performance barrier

#20

> Wasm-bindgen calls TextDecoder.decode for every string. Sledgehammer only calls TextEncoder.decode once per batch. So they decode one long concatenated string and then on the JS side split it into substrings? I wonder if that messes with the GC on the JS side of things.

How would splitting it into substrings be different from decoding individual strings from an allocation/gc perspective? If anything I'd assume splitting a substring was more efficient - i expect there's a ton of optimisations in js for sliced strings or whatever as it's been around for ages.

I imagine it's faster during creation because there's fewer allocations for a backing array for the string content (one, basically, unless they move stuff around). But then that can also mean holding on to the entire backing array even if only one of the strings is still "alive", unless there are optimizations for reclaiming memory in those situations too.
Post reply on HN