just-js / lo

it's JavaScript Jim, but not as we know it. :space_invader:
MIT License
241 stars 10 forks source link

Cross Platform FFI ultra fast method spoted #34

Open lemanschik opened 6 months ago

lemanschik commented 6 months ago

i saw on your todo cross platform ffi read this repo about that lets apply same method.

dyncall is used to make dynamic calls to native functions. In order to avoid some cost of translating JavaScript values into raw C types, a shared buffer is used for both arguments and return values. Writing values to a buffer turns out to be quite a bit faster than unpacking them in native code.

billywhizz commented 5 months ago

hi frank. yeah, we do something similar in lo for ffi. libffi has quite a bit of overhead. you can see here that for a v8 fastcall, the overhead is negligible using our method. for a non-fastcall the overhead is ~2x compared to a native compiled binding which, afaik, should still be faster than any of the ffi methods used in node.js.

https://github.com/just-js/docs/blob/main/example/ffi/README.md

Deno has very fast FFI also. it generates ASM dynamically from Rust. In lo, we generate the ASM with our mini assembler, all from JS. it only works for x64 right now but should be easy enough to port it to arm64/others.

xyloflake commented 5 months ago

i saw on your todo cross platform ffi read this repo about that lets apply same method.

dyncall is used to make dynamic calls to native functions. In order to avoid some cost of translating JavaScript values into raw C types, a shared buffer is used for both arguments and return values. Writing values to a buffer turns out to be quite a bit faster than unpacking them in native code.

FYI, lo's ffi is very fast. SBFFI is one of the slowest ones when it's compared. This is a comparison as posted on the discord server by @billywhizz image

billywhizz commented 5 months ago

FYI, lo's ffi is very fast. SBFFI is one of the slowest ones when it's compared. This is a comparison as posted on the discord server by @billywhizz

yes. there is quite some overhead. that graph shows a call to a function that is doing quite some work (counting lines in a buffer). i'll see if i can get one that just tests the ffi overhead on a noop(). among the mainstream runtimes, deno ffi and then bindings seem to be quite a bit less overhead than any of the other ffi methods. afaik, deno ffi and lo ffi/bindings are only ones currently using v8 fastcalls.

xyloflake commented 5 months ago

@billywhizz see if you can write a blog post about how bindings in lo work, pretty darn sure everyone would love it.

Also why is this issue still open? Will you be using to track cross platform ffi support? In that case please change the title of the issue.

lemanschik commented 4 months ago

@xyloflake whats your take about #40