5 ms·
I'm bullish on Rust, but there's a long way still to go. The overhead of passing values across the boundary between JavaScript and Rust is quite high. There are
by segphault 4y ago
I'm bullish on Rust, but there's a long way still to go. The overhead of passing values across the boundary between JavaScript and Rust is quite high. There are a lot of cases where you want to be able to provide a dynamic configuration to something on the Rust side, ideally from JavaScript, and that's still pretty costly from a performance perspective.
One of my projects (https://markdoc.dev/ https://markdoc.dev/) is a Markdown dialect that supports custom tags and a React renderer. I recently experimented with implementing a parser for it in Rust in order to increase performance. My Rust-based parser is significantly faster than my existing JavaScript parser, but then I have to serialize the AST in order to move it from Rust to JavaScript. I'd like to implement the entire processor in Rust, but I need to let users define custom tags in JavaScript, and the overhead of going back and forth is far from ideal.
I'm hopeful that the recently-ratified Wasm GC proposal—which introduces managed structs and arrays that don't cost anything to pass between the Wasm environment and JavaScript—will help a lot. But it's going to take awhile for Wasm GC features to land in LLVM and be properly supported in Rust.
- samsquire 4y agoMozilla abandoned XPCOM partly due to the runtime cost of marshalling between C++ and JavaScript. https://yoric.github.io/post/why-did-mozilla-remove-xul-addons/ https://yoric.github.io/post/why-did-mozilla-remove-xul-addo... I wonder if the solution is transpiling. If Javascript was transpiled to Rust, there would be less data to copy. You would just have two API surfaces. But you wouldn't have runtime Javascript execution, just the capability of running Javascript code at native performances.
- jraph 4y ago> If Javascript was transpiled to Rust Seems challenging. JavaScript code does not come with lifetime information that the Rust compiler expects to have to get rid of stuff that's not used anymore, while JS has a garbage collector to do this. There's also no borrowing information encoded in JavaScript code. Rust expects the developers to provide this information in their code so it knows who and where what can modify what.
- KMag 4y agoI believe automatically inferring lifetimes in the general case is equivalent to solving the halting problem (for every sub-program, determine if a given reference is stored to the heap before the sub-program terminates), so transipiling JS to Rust would presumably need manual lifetime annotation or else require significant limitations to simplify lifetime analysis.
- kaba0 4y agoRust’s lifetimes can’t express arbitrary lifetimes, only “stack-like” ones. Other kinds are very frequent in managed languages and are only possible to deal with due to the GC.
- satvikpendem 4y agoThis article is more so talking about tooling like SWC rather than using WASM as the bridge between JS and Rust. Personally I feel that the former is much more important than the latter which doesn't seem to have as many benefits for people making web apps on average. Sure, if you're running something very intensive like a video editor like Veed or a design tool like Figma, WASM is nice, but most web devs are making CRUD apps.
- segphault 4y agoThe underlying problem is still highly relevant in relation to JavaScript build tooling. Let's say that you have a transpiler written in Rust and you want to write a plugin that performs a custom AST transform. If you want to be able to write the plugin in JavaScript, you have to take the AST from Rust and convert it to a JavaScript data structure in order to pass it into the plugin and then you have to convert the output back into a Rust data structure on the other end. Or you have to provide a JavaScript API that can safely mutate a Rust data structure from JavaScript while converting primitive values each way on demand. This is exactly like the problem I described with my Markdown processor. There's a ton of overhead involved, and it can cancel out a depressing amount of the performance gain that you would otherwise get from moving things to Rust. Ultimately, these build tools need to have some degree of programmatic extensibility, and people want to get that without having to write their domain-specific logic in Rust and recompile the whole binary. There needs to be a better extensibility story and a cheaper (ideally, zero-copy) way to share data across the language boundary.
- satvikpendem 4y agoThat's true that it needs more extensibility and zero-copy sharing of data, but in your example, are you serializing to something like JSON? Why does the end user need to specify the tags in JavaScript particularly and not something like JSON? Forgive me if I'm not understanding and you are indeed using JSON.
- segphault 4y agoMarkdoc custom tag definitions can include arbitrary AST transforms on the child nodes, as in this example: https://markdoc.dev/docs/examples#tabs https://markdoc.dev/docs/examples#tabs In order to do this, you need some API, so you can't just define the tags in JSON.