component-model icon indicating copy to clipboard operation
component-model copied to clipboard

Optimization: Shorter option binary representation via invalid value (e.g. -1 == None of option<resource>)

Open cpetig opened this issue 11 months ago • 3 comments

Today I realized that option<my-resource> or option<borrow<my-resource>> could have the same size and representation as the resource itself, because (at least in the current bindings) -1 is used as an invalid value for the resource index.

As I didn't find the invalid value nor the optimization documented in the canonical ABI, I wonder whether this would be a reasonable addition to the spec. Similarly string and vector could have defined invalid representations which could optimize the representation of an option.

See https://doc.rust-lang.org/std/option/index.html#representation for the documentation of the Null Pointer Optimization on Rust.

cpetig avatar Jan 11 '25 18:01 cpetig

As I didn't find the invalid value nor the optimization documented in the canonical ABI

You’re probably looking for #284.

primoly avatar Jan 11 '25 22:01 primoly

Right, so 0 would be the externally agreed invalid id (instead of the -1 I see in wit-bindgen code)

It makes perfect sense but I wonder whether this is already implemented in wasmtime and jco this way (I recall seeing zero handles for the first object of each type many times in the past using these runtimes).

And then this issue proposes to use that as a sentinel value to optimize the canonical representation of option<my-resource> as a mere s32.

cpetig avatar Jan 11 '25 23:01 cpetig

Abstractly this makes sense. Mostly, I didn't dig into this sort of optimization initially because I was worried it was a rabbit hole that one could go quite far down in a way that gets baked into a spec that forces N produces+consumers to have to care about, so I wanted to get some implementation feedback and motivation. But if we think this could be a meaningful win in practice, I think it could work.

Because we're currently in the "island of stability" that is wasip2 which we want to maintain in wasip3, I don't think we can make this change without some opt-in canonopt (and then over time we could deprecate the unset option, and then flip the default in 1.0). Doing a whole canonopt for a small optimization seems to require a bit of effort, but perhaps we could fold it in with another batch of ABI changes; say lazy lowering?

lukewagner avatar Jan 14 '25 01:01 lukewagner