-
Notifications
You must be signed in to change notification settings - Fork 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 QuickJS as a Javascript engine option #4622
Conversation
Some quick and dirty benchmarking TL;DR:
Needs more benchmarking but so far looks decent. And the lower resource consumption should be a benefit running in the new fedramp kube environment. Setup Details MacOS Intel, Erlang 24, ./dev/run -n1 Benchmark script: https://gist.github.com/nickva/c0cbf6a556cc2dc7dd6ee79f504f5f84.
Results measured by the zsh QuickJS
Memory usage 5MB-7MB RSS per couchjs process (based on btop output) Spidermonkey 1.8.5
Spidermonkey 91
Memory usage 30-32MB RSS per couchjs process (based on btop output) Runtime metrics capture (also quick and dirty courtesy of btop): ![]() ![]() The CPU usage graph is quite telling I think. |
https://bellard.org/quickjs https://fuchsia.googlesource.com/third_party/quickjs/ Some benefits over SM: * Small. We're using 6 or so C files vs 700+ SM91 C++ files. * Built with Apache CouchDB as opposed having to maintain a separate SM package, like for RHEL9, for instance, where they dropped support for SM already. (see apache#4154). * Embedding friendly. Designed from ground-up for embedding. SM has been updating the C++ API such that we have to keep copy-pasting new versions of our C++ code every year or so. (see apache#4305). * Easy to modify to accept Spidermonkey 1.8.5 top level functions for map/reduce code so we don't have have to parse the JS, AST trasform it, and then re-compile it. * Configurable runtime feature set - can disable workers, promises and other API and features which may not work well in a backend JS environment. Some users may want more, some may want to disable even Date(time) features to hedge again Spectre-style attacks (spectreattack.com). * Allows granular time (reduction) trackign if we wanted to provide a runtime allowance for each function. * Better sandboxing. Creating a whole JSRuntime takes only 300 microseconds, so we can afford to do that on reset. JSRuntimes cannot share JS data or object between them. * Seems to be faster in preliminary benchmarking with small concurrent VDU and view builds: https://gist.github.com/nickva/ed239651114794ebb138b1f16c5f6758 Results seem promising: - 4x faster than SM 1.8.5 - 5x faster than SM 91 - 6x reduced memory usage per couchjs process (5MB vs 30MB) * Allows compiling JS bytecode ahead of time a C array of bytes. QuickJS can be built alongside spidermonkey and toggled on/off at runtime: ``` ./configure --dev --js-engine=quickjs ``` This makes it the default engine. But spidermonkey can still be set in the config option. ``` [couchdb] js_engine = spidermonkey | quickjs ``` Only tested on MacOS and Linux. All `make check` tests pass there.
This looks to be a great improvement on several fronts. I think we should go all in on this. maybe optional for a release or two and then fully switch? once we can assume an embedded JS engine we can boost a number of areas (like VDU's). |
Switching pull request to use the branch off the Apache CouchDB main since otherwise Jenkinsfile updates don't have an effect. Closing in favor of #4627 |
https://bellard.org/quickjs
https://fuchsia.googlesource.com/third_party/quickjs/
Some benefits over SM:
Small. We're using 6 or so C files vs 700+ SM91 C++ files.
Built with Apache CouchDB as opposed having to maintain a separate SM package, like for RHEL9, for instance, where they dropped support for SM already. (see RHEL 9 Support for CouchDB #4154).
Embedding friendly. Designed from ground-up for embedding. SM has been updating the C++ API such that we have to keep copy-pasting new versions of our C++ code every year or so. (see try compiling for sm 102 #4305).
Easy to modify to accept Spidermonkey 1.8.5 top level functions for map/reduce code so we don't have have to parse the JS, AST trasform it, and then re-compile it.
Configurable runtime feature set - can disable workers, promises and other API and features which may not work well in a backend JS environment. Some users may want more, some may want to disable even Date(time) features to hedge again Spectre-style attacks (spectreattack.com).
Allows granular time (reduction) trackign if we wanted to provide a runtime allowance for each function.
Better sandboxing. Creating a whole JSRuntime takes only 300 microseconds, so we can afford to do that on reset. JSRuntimes cannot share JS data or object between them.
Seems to be faster in preliminary benchmarking with small concurrent VDU and view builds: https://gist.github.com/nickva/ed239651114794ebb138b1f16c5f6758 Results seem promising: - 4x faster than SM 1.8.5 - 5x faster than SM 91 - 6x reduced memory usage per couchjs process (5MB vs 30MB)
Allows compiling JS bytecode ahead of time a C array of bytes.
QuickJS can be built alongside spidermonkey and toggled on/off at runtime:
This makes it the default engine. But spidermonkey can still be set in the config option.
Only tested on MacOS and Linux. All
make check
tests pass there.Issue: #4448