nanovms / ops

ops - build and run nanos unikernels
https://ops.city
MIT License
1.27k stars 132 forks source link

JustJS compatability? #1058

Closed tomByrer closed 3 years ago

tomByrer commented 3 years ago

There is a webserver benchmark I visit to see what platform is the fastest, & was surprised that a JavaScript platform that's Linux-only with custom V8-bindings, JustJS is the second-fastest web framework, beating out almost all C++ & Rust frameworks.

I'm still in the researching stage, & don't know C++ & Go enough to hack, but curious if you or @billywhizz could give insights.

Sadly, your NodeJS benchmarks confirmed my fear; NodeJS is slow, but seems JavaScript doesn't have to be slow.

TIA!

eyberg commented 3 years ago

interesting - both the statically compiled hello world and from the interpreter seems to work for me:

eyberg@box:~/j/hello$ just build hello.js --clean --static
clean hello rm -f *.o
rm -f hello
complete in 0.1 sec
build hello 0.0.22 (just.js) gcc builtins.S -c -o builtins.o
g++ -c -fno-exceptions -ffunction-sections -fdata-sections  -DJUST_VERSION='"0.0.22"' -std=c++17 -DV8_COMPRESS_POINTERS -I. -I./deps/v8/include -O3 -march=native -mtune=native -Wpedantic -Wall -Wextra -flto -Wno-unused-parameter just.cc
g++ -c -fno-exceptions -ffunction-sections -fdata-sections  -std=c++17 -DV8_COMPRESS_POINTERS -I. -I./deps/v8/include -O3 -march=native -mtune=native -Wpedantic -Wall -Wextra -flto -Wno-unused-parameter main.cc
g++ -s -static -flto -pthread -m64 -Wl,--start-group deps/v8/libv8_monolith.a main.o just.o builtins.o modules/sys/sys.o modules/fs/fs.o modules/net/net.o modules/vm/vm.o modules/epoll/epoll.o -Wl,--end-group -Wl,--gc-sections  -ldl -lrt -o hello
complete in 9.5 sec
eyberg@box:~/j/hello$ ./hello
hi world!
eyberg@box:~/j/hello$ ops run hello
booting /home/eyberg/.ops/images/hello.img ...
en1: assigned 10.0.2.15
hi world!
eyberg@box:~/j/hello$ ops run -c c.json /usr/local/bin/just
booting /home/eyberg/.ops/images/just.img ...
en1: assigned 10.0.2.15
hi world!
eyberg@box:~/j/hello$ cat c.json
{
  "Files": ["hello.js"],
  "Args": ["hello.js"]
}
eyberg@box:~/j/hello$ cat hello.js
just.print("hi world!")

we could make a pkg for the just interpreter but i'm going to guess that that static compilation way is going to be the faster option

billywhizz commented 3 years ago

There is a webserver benchmark I visit to see what platform is the fastest, & was surprised that a JavaScript platform that's Linux-only with custom V8-bindings, JustJS is the second-fastest web framework, beating out almost all C++ & Rust frameworks.

I'm still in the researching stage, & don't know C++ & Go enough to hack, but curious if you or @billywhizz could give insights.

Sadly, your NodeJS benchmarks confirmed my fear; NodeJS is slow, but seems JavaScript doesn't have to be slow.

TIA!

hi @tomByrer. yes. i have been sidelined a bit recently by other issues but i have been working on a more usable web framework more akin to node.js/express api's and from what i can see so far it will add very little overhead to the pretty ugly code currently running in the TE benchmarks. that code was really a proof of concept and an attempt to go "as fast as possible" without any complex abstractions so i can set a baseline for performance and future development. once i have the changes i am working on near completion i will create a separate Raw/Realistic entry for TE and am hopeful there will be little between them.

v8/JS is indeed blazing fast. it's definitely possible to get very fast performance from JS web servers but you need to be very careful about how you write your code and especially with allocating objects and creating garbage.

Node.js has a lot more layers to go through - mountains of overly complex (imho) js and also libuv, whereas just-js is pretty much straight on the metal with little or nothing between it and the syscall interface. of course there are tradeoffs - it's currently linux/x86_64 only but i think could be ported to BSD/Mac without much added complexity.

billywhizz commented 3 years ago

interesting - both the statically compiled hello world and from the interpreter seems to work for me:

eyberg@box:~/j/hello$ just build hello.js --clean --static
clean hello rm -f *.o
rm -f hello
complete in 0.1 sec
build hello 0.0.22 (just.js) gcc builtins.S -c -o builtins.o
g++ -c -fno-exceptions -ffunction-sections -fdata-sections  -DJUST_VERSION='"0.0.22"' -std=c++17 -DV8_COMPRESS_POINTERS -I. -I./deps/v8/include -O3 -march=native -mtune=native -Wpedantic -Wall -Wextra -flto -Wno-unused-parameter just.cc
g++ -c -fno-exceptions -ffunction-sections -fdata-sections  -std=c++17 -DV8_COMPRESS_POINTERS -I. -I./deps/v8/include -O3 -march=native -mtune=native -Wpedantic -Wall -Wextra -flto -Wno-unused-parameter main.cc
g++ -s -static -flto -pthread -m64 -Wl,--start-group deps/v8/libv8_monolith.a main.o just.o builtins.o modules/sys/sys.o modules/fs/fs.o modules/net/net.o modules/vm/vm.o modules/epoll/epoll.o -Wl,--end-group -Wl,--gc-sections  -ldl -lrt -o hello
complete in 9.5 sec
eyberg@box:~/j/hello$ ./hello
hi world!
eyberg@box:~/j/hello$ ops run hello
booting /home/eyberg/.ops/images/hello.img ...
en1: assigned 10.0.2.15
hi world!
eyberg@box:~/j/hello$ ops run -c c.json /usr/local/bin/just
booting /home/eyberg/.ops/images/just.img ...
en1: assigned 10.0.2.15
hi world!
eyberg@box:~/j/hello$ cat c.json
{
  "Files": ["hello.js"],
  "Args": ["hello.js"]
}
eyberg@box:~/j/hello$ cat hello.js
just.print("hi world!")

we could make a pkg for the just interpreter but i'm going to guess that that static compilation way is going to be the faster option

hi @eyberg. i'm just now seeing the ops project - it looks really interesting. just-js should be a good fit for JS inside a VM and that is one of the original use cases i saw for it. you can statically compile/bundle the whole application including c++ modules and all JS code into a single binary, which is great for packaging and deployment. it's also more secure as you can then ensure no external code is loaded at runtime and the only code that will run is what was compiled into the binary.

happy to discuss further or provide any help if you are experimenting - i realise the documentation is severely lacking at moment and will hopefully have a new revision with better docs and examples up soon.

billywhizz commented 3 years ago

@eyberg @tomByrer i've also done some experiments with seccomp which might be useful for running in a restricted environment: https://github.com/just-js/examples/blob/main/misc/seccomp.js. it's very easy to hook just-js up to any c/c++ api you need. i have a reasonable ffi module working too. here are some sqlite bindings using ffi: https://github.com/just-js/examples/blob/main/ffi/sqlite.js.

tomByrer commented 3 years ago

Thanks for looking into this everyone!

I really liked the idea of Cloudflare Workers since the only modern language I know is JavaScript, but I'm afraid of hosting lock-ins. I can see NanoVMS as a great way to deploy true microservices using FSM/Statecharts. I love XState's API, but NodeJS is not the best fit for short lived performant job runner. JustJS seems to prevent me from having to learn C.