Hi! I have some string literals that will only ever be accessed on the host (e.g., in other host functions called from the guest), so I was wondering the recommended approach for handling this.
I know it's possible to basically intern all of the strings and pass a handle (e.g, as u32
) back from the guest, but I was wondering whether it might work nicely to use ExternRef
s for this - basically every string would become an ExternRef
that is all handled by the host. I think this would mean I'd have to make the function dynamic (i.e., because I don't know how many strings are needed statically), so something like Func::new(&mut store, type_with_all_strings_as_params, |_, params, results| { /*...*/ })
.
Am I thinking about this right? Both approaches seem to work fine in practice, though ExternRef
feels slightly more convenient since I don't have to worry about managing the string interning. I don't have a good intuition of how much overhead the runtime type checking for dynamic ExternRef
params compares vs. the overhead of the interned string lookups, so I was wondering if somebody might have an idea? Thank you!
I think that the performance difference between interning and externref
shouldn't be huge because internally they are the same. The externrefs will be more convenient indeed since the runtime handles all the details for you and can automatically free the strings when you are done using them. One big difference that you should keep in mind is that a u32 can be stored directly into wasm linear memory behind a normal pointer. This can also be dealt with by storing the externref into a wasm table of externrefs and passing around the indices into the table. The benefits of this compared to interning the strings yourself are:
externref
into linear memoryAs a caveat, I'm mostly used to using the JS api for wasm with C code, there may be additional benefits/costs of the two methods are if you use wasi and Rust instead.
Awesome, thank you for the context and suggestions! I've started with interning for now and also using that to write to intermediary strings (e.g., result of doing string concatenation would create a new interned string on the host side and the guest just gets a u32 for the resulting string) but interested in trying out externref
more soon. The table idea is really interesting
Last updated: Dec 23 2024 at 12:05 UTC