json
json•11mo ago

filter performance

I'm reading the post about normal ts filters, and it says it works "with the same performance as built-in Convex filters". Do the q.eq, q.neq, q.lt (...) objects not compile to something more efficient than JS? https://stack.convex.dev/complex-filters-in-convex
11 Replies
lee
lee•11mo ago
the query builder for .filter compiles to filters that run in Rust, which is slightly more efficient than JS. But not much, since the JS itself runs on the Rust/C++ V8 runtime (the same one Chrome uses). As the article's footnote mentions, efficiency of executing a filter is overshadowed by changes to the data scanned, like .withIndex.
json
jsonOP•11mo ago
I see. But there is a difference from using the q... objects, and using js operators/functions, correct?
lee
lee•11mo ago
Yes, i'm just saying the performance difference is negligible. You can measure it if you want 🙂 and if you want to see how the operators execute, the source code is https://github.com/get-convex/convex-backend/blob/main/crates/common/src/query.rs#959
GitHub
convex-backend/crates/common/src/query.rs at main · get-convex/conv...
Open source single-machine version of the Convex backend - get-convex/convex-backend
json
jsonOP•11mo ago
no problem, thanks a lot so... some more curiosities on the runtime. since convex limits npm packages for queries and mutations, does 100% of the js code get transpiled to rust? 👀 or is it interpreted
lee
lee•11mo ago
It's interpreted, running in the same JS runtime that Chrome uses https://v8.dev/ . The restriction in packages is because it doesn't implement the node apis, just the browser ones, and doesn't allow nondeterminism or side effects in queries or mutations (so anything that uses fetch)
V8 JavaScript engine
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
json
jsonOP•11mo ago
I see. So what parts of convex get special treatment by rust?
lee
lee•11mo ago
1. anything called on ctx (like ctx.db.query(...).filter(...) ) 2. anything V8 doesn't implement that is part of standard browsers, like fetch 3. parts of V8 we tweak for determinism and side effects, like console.log, Date.now(), and Math.random() See source code https://github.com/get-convex/convex-backend/tree/main/npm-packages/udf-runtime/src
GitHub
convex-backend/npm-packages/udf-runtime/src at main · get-convex/co...
Open source single-machine version of the Convex backend - get-convex/convex-backend
json
jsonOP•11mo ago
I see. I'm surprised that there isn't a significant difference for filters that run in rust vs js, but I believe you :) Thanks for the info @Lee is there a chance we also get map() reduce() with some more builtin operators? I'm looking for ways to auto-generate indexes (or materialized views) based on the shape of the query, and it would for these to be compiled to rust instead of plain js
lee
lee•11mo ago
we've discussed adding built-in joins and field selection. But we haven't added it yet because anything we add a. will be custom syntax you need to learn b. won't be able to cover all use-cases c. won't be much of a performance improvement. If we do add this support, the main reasons will be: a. make the pattern look more supported / "blessed" b. allow automated detection of inefficient cases that can be replaced by indexes (this is the main reason why .filter exists, even though we don't do this right now) So we recommend doing maps and joins and reduce in js. If you're seeing bad performance, please measure it (like with console.time) and reach out to see how we can help.
json
jsonOP•11mo ago
I see. If in future testing there aren't any complaints about raw js performance, will you guys considering keeping the JS filter by default?
lee
lee•11mo ago
i'm not sure what you're asking. We're likely going to keep both the rust-executing db.query(...).filter(...) and js-executing filter(db.query(...), ...) as options, for backwards compatibility if nothing else.

Did you find this page helpful?