-
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
sql.js is almost 2 OOM slower than WebSQL on the same query (identical set of tables, rows, views, indices, hw, browser) #225
Comments
It's hard to say anything without actually seeing the code. But indeed, sql.js is slower than anything native, and handwritten code is usually faster than using even a native SQL implementation. |
Thanks @lovasoa I'll try to brew a minimal set of queries that shows the difference without less relevant domain-specific content, although as you suggest, probably not much can be done about it in |
... also, with upcoming Spectre / Meltdown bug fixes, there may be negative impact on asm.js / WASM |
By the way, I forgot to ask, but do you use prepared statements ? |
The render loop was as simple as
I can't prepare the
This change resulted in a very nice 2-3x speedup for the version which has all |
P.S. I used your suggestion and added back the |
WebSQL is deprecated. Why do you even bother? |
I know. Some of my interests were:
while
etc., so in short, learning. |
@Taytay not really - I hooked up a few tables and a bunch of views atop of the tables and other views, updated some input table on every requestAnimationFrame and in turn, queried the top level view. It wasn't a lot of data but quite a few views in a relatively deep graph, joining small views/tables with one another, selection, aggregation etc. Lmk if I should I send the test page to your mailbox as seen on gh (or elsewhere) or dm me on twitter |
@monfera : This issue is closed, but now that #255 is merged, SQL.js is compiled into WASM, which is faster, but not an Order of magnitude faster. :) Still, I'd be curious what you found in your tests with the new version. In my testing, the more you can keep in the WASM code, the better. Calling across the boundary into WASM via multiple calls to prepare, bind, and execute are going to be slow. I was recently experimenting with simply batching inserts to see how fast I could get things, and even when I was using I don't know if the current version of SQL.js is compiled to know that everything should be "in memory", which might be a faster way to run SQLite. I've got an experimental branch open that removes some features and made things at least twice as fast, but it's a bit out of date now : Taytay#1 Also, you said that you can't use prepare because it is "select specific", but I think if you prepared your statement : update desiredWindowSize
set width = ?,
height = ? and then ran bind to give it the exact parameters, that would work, right? I wasn't sure I followed. |
Adding some input relating to this closed item; it can be immediately closed as there aren't many things to try, but maybe someone has an idea of the cause, or helps spot some perf issue, or at least I could learn how others use
sql.js
when it appears to be really slow when there are a few dozen related tables/views, even with only 150 input rows.I ended up implementing some interactive visualization in pure SQL (sans a single input and DOM element update) where there are about 5 input tables (one with 150 rows, the other 4 are with 1..4 rows), and a few dozen views that build on these four tables and on each other, using all kinds of basic things (groupBy, union, join etc. but nothing fancy computationally). There's one final query whose result is used to output the result - redraws 150 circles on the screen (rendering is negligible time cost).
The calculations generate an X and Y scale for this prototype scatterplot, such that the rectangular area (whose size is the input, a.k.a. responsive design) is optimally filled with the circles, but no circle gets truncated (it can be seen on the image that the circles at the edges touch the image border):
Initial result: one render taking around one minute.
Subsequent tweaks:
cross join
s (which bind the hand of the optimizer in SQLite)UPDATE
of the single record of two columns in that table), which channels into the midsection of the entire DAG of views; many views which were upstream of this dynamic input in the DAG were converted to a table, but of course nothing downstream can be converted as they'd become nonresponsive, SQLite doesn't have materialized views let alone incrementally updating materialized viewsThese changes resulted in an update time of 1.5 seconds.
explain query plan
wasn't a big help for two reasons:create table ... as select ...
; yet for views, which do the work (incl. creating a new column whose value is a very simple calculation on the other fields of the row), one cannot create indices, so there are a couple ofUSING TEMP B-TREE (UNION)
and the like.I then thought, why not try it with WebSQL, which is about the same SQLite but runs native. I got somewhat varying frame rates, typically between 15..20FPS, sometimes 30FPS.
==========
In sum, the same exact set of views updated in 1500ms with
sql.js
and in 50ms with WebSQL, though I could add ananalyze
tosql.js
but not to WebSQL.So this is 1-2 orders of magnitude slower speed, quite unexpected, especially because the
sql.js
version benefits from not having to go through a browser API boundary (though it's a minor point as the single final query just retrieves 150 rows with 5 numeric columns).Note: even the 50ms update is quite slow, as a woefully non-optimized plain JS version, which just materializes all views (corresponding to pretty much the same queries with a winged multiset relational algebra DAG), and rebuilds fully if invalidated, runs in a fraction of that time. Also, that 50ms was achieved at the expense of 1) quite heavy tweaking, esp. selecting into tables rather than views where sensible; 2) reducing the generality, because now only one of the 5 tables can accept insert/update changes; if I retain full DAG recalc flexibility ie. all but the 5 tables are views, then the numbers are even farther:
simple, fully recalculating DAG in JS: ~10ms < WebSQL: ~150ms <
sql.js
: 9400msNow I wonder about real use cases where there may be more than 150 rows and mildly nontrivial views (or compound selects) where people find
sql.js
sufficiently fast. It's a weighty dependency to consider (2.6MB) so I'm interested in if, and how folks are using it.The text was updated successfully, but these errors were encountered: