4 ms·
I don't buy this argument. WebAssembly is a vastly different beast than trivial C extensions (since WASM is a browser thing). JavaScript has both and is still
by brrrrrm 4y ago
I don't buy this argument. WebAssembly is a vastly different beast than trivial C extensions (since WASM is a browser thing). JavaScript has both and is still much faster.
Bun (the runtime I used for the post), has a native C interface that's far simpler to use than Python (even with pybind/nanobind):
https://github.com/oven-sh/bun#bunffi-foreign-functions-interface https://github.com/oven-sh/bun#bunffi-foreign-functions-inte...
Deno (a v8-based runtime) has the same thing: https://deno.land/manual@v1.25.4/runtime/ffi_api https://deno.land/manual@v1.25.4/runtime/ffi_api
These use the standard C-ABI directly without requiring headers (unlike Python).
Node.js standardized a more Python-like C API called Node-API: https://nodejs.org/api/n-api.html https://nodejs.org/api/n-api.html
I believe Python can continue to add performance and is not hamstrung by the implementation.
- cogman10 4y agoThe difference between all of these and how the python c api works is that 1 layer of abstraction and translation. Take the deno example, in order to invoke a C function you have to tell deno "load this lib, this dynamic function is here, and the method signature looks like this". Look at what types are permitted to be passed between the two as well. deno isn't exposing deno objects to C, it's exposing only simple primitive types. The cpython FFI, on the other hand grants C full access to python objects. That one layer of abstraction and distance makes all the difference and is hard to backport in. There's a reason alternative pythons (pypy, graalpy) don't really support it and struggle to support libs that rely heavily on it (like tensorflow).
- brrrrrm 4y agoYou can expose objects. Here's how it is done in Bun: https://github.com/facebookresearch/shumai/blob/main/shumai/tensor/tensor.ts#L277 https://github.com/facebookresearch/shumai/blob/main/shumai/... We've been using this feature heavily in Shumai. I think you are vastly overestimating the complexity associated with this (user exposed ref-counting/garbage collection) and may not be totally up to date on what's implemented.
- cogman10 4y ago> I think you are vastly overestimating the complexity associated with this No, I think you are misunderstanding the problem. I'm not saying that, with a good 3rd party lib, generating FFI APIs can't be easy and slick. I'm saying that non-python languages have more complicated FFI APIs that practically necessitate these sorts of generation libraries (like bun). When you grab a bit of memory out of an object in C with python, you are reaching directly into python's internal representation of the object and tickling the bits there. When you do that with deno/javascript/others, there's a layer of abstraction introduced to keep our native method from directly tickling the bits that the VM is aware of. That's the problem. From C, you can create a new python object, store it off in a global variable, send it back to the python vm, and later in a thread go tickle some of the bits and see that tickling in the Python VM. Because that object is the same one used by Python and C. The complication that arises with CPython is many very popular librarys (numpy, tensorflow, pandas) rely HEAVILY on the fact that the objects they are working with in C are the same ones python uses. That's why they've been so slow to port to pypy if at all. And that ability for C libraries to very deeply interact with the VM is exactly the problem that makes it hard to improve CPython's JIT. That's the reason other python JITs, like pypy, either don't or have very limited support for CPython's FFI capabilities. The reason FFI works so well with other languages is they drew very tight and clear boundaries around how interactions work and who owns what when. So please, stop spamming "bun". It's a non sequitur.
- brrrrrm 4y agoI'll concede that Python has more nuanced bits of complexity exposed, but I suspect a willingness to break compatibility for the sake of performance would benefit the language a lot more than it would hurt it. I personally hope the hacker mentality and the immensely perf-driven nature of JavaScript is one day adopted by Python. For those following, I want to make it clear that the "bits" being discussed are extremely nuanced and won't get in the way of doing obviously useful things in JavaScript. Here's how you create a JS Object from C using Node-API: https://nodejs.org/api/n-api.html#napi_create_object https://nodejs.org/api/n-api.html#napi_create_object It conforms to ECMAScript 6.1.7 Object Types and is very much the same internal representation used by the VM. Here's how one might tickle the internal representation used by Node.js (V8 in this case) to change the value of the underlying property of a JavaScript object from C: https://nodejs.org/api/n-api.html#napi_set_element https://nodejs.org/api/n-api.html#napi_set_element