-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
add support for passing Rust Iterators into JS as iterables #1478
Comments
As a workaround, you can use This does cause a minimum of two allocations (one to convert to a Rust I'm not sure if that's actually slower than sending an iterator to JS, since iterators would require ping-ponging back and forth many times between Rust and JS (and it has to allocate a JS object once for each element!) It would be good to get some benchmarks verifying which approach is faster. |
@Pauan Aside from performance difference, it's important to consider a usecase of infinite iterators too - these are not completely uncommon in lazy scenarios, and wouldn't be possible to collect into a temporary |
Although, rather than solving this particular issue on its own, it seems to be a narrow case of a potentially more general "allow exposing |
Also, working on things piecemeal through an iterator is helpful for avoiding UI jank, whereas computing a few thousand entries in one go to stuff into a It can be seen as an instance of |
@RReverser Sure, you're right of course that infinite iterators cannot use Also, how would we be able to use @shaver Ironically, in a large JS library I work on for a company, we used ES6 iterators extensively, but we had to remove all of them, because allocating an object for each element was causing massive UI jank (because of all the garbage collection). Doing things piecemeal doesn't help, because the main issue isn't raw CPU performance, the main issue is garbage collection (which happens sporadically, and completely locks up the UI for hundreds of milliseconds). That's why game engines obsess so much about memory management. In my experience it's rare for the CPU to be the bottleneck, garbage collection or the network tend to be much more important. Of course there are certain situations where the CPU really is the bottleneck, but even then I think a If you have a rather large iterator (say... hundreds of thousands of elements), I think a better solution is to split the iterator into chunks (so you'd make a In fact, if you reused the same That gives you the best of both worlds: you aren't allocating on every element, so it dramatically minimizes the amount of garbage collection, but it still avoids allocating the entire Theoretically this could even handle infinite iterators, though that seems like a more tricky subject. |
Any update on this subject? Are there any workaround to have an iterable on the JS side? |
I'm struggling with how to define the iterable interface at all in Rust. I can make a I can do |
@bovee You have to use Reflect::set(&object, &Symbol::iterator(), my_function).unwrap(); Alternatively you can use #[wasm_bindgen(inline_js = "
export function foo(obj) {
obj[Symbol.iterator] = function () {
return this;
};
}
")]
extern "C" {
fn foo(obj: &Object);
} Now you can call |
With your second snippet (and finally learning how to run code at init), I was finally able to replace this last bit of JS. Thanks so much! If anyone's trying to figure out how to manually do this in the future before library support happens, this is what I came up with: #[wasm_bindgen(start)]
pub fn start() -> Result<(), JsValue> {
...
// This works, but I couldn't figure out how to get the prototype of an object without instantiating a copy first
foo(&Object::get_prototype_of(&instantiated_object.into()));
Ok(())
} |
Is there a complete code snippet? I don't understand how it is done? Forgive me for being new to js |
Rust's Iterators underlie a lot of useful patterns, and it would be great to be able to express them to JS for natural interactions as iterables.
This might be the inverse of #1036 ?
The text was updated successfully, but these errors were encountered: