-
Notifications
You must be signed in to change notification settings - Fork 643
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
[DISCUSSION] Compile to Native/Machine binary instead of Hermes VM #395
Comments
Compiling a dynamic language like JavaScript to native code ahead of time is still a research topic, but the established consensus is that it is impossible to do without sacrificing performance, code size, or usually both. Basically, if we compiled JavaScript to ARM, while accurately preserving the language semantics, the result would be at least 5x larger, and would likely have only a marginal performance improvement, if any. In fact, the 5x increase in size is itself so prohibitive that the performance improvement becomes irrelevant. Instead of a 5MB bytecode bundle, you would get a 25MB or even a 50MB native shared library. The same applies to targeting WebAssembly. We have performed internal experiments with ahead of time native code generation and the results were as expected. To understand the size increase and the disappointing performance, here is a simple example:
This translates to a single bytecode instruction, which is 4 bytes long. But let's consider what we need to do if we are generating native code. At compile time we don't know the types of
|
But still WebAssembly support will be very beneficial. First, we can utilize a lot of interesting emerging projects from Web community. It's much more simple to use some WebAssembly than writing own (or adopt others) C++ code through JSI. There is a lot of potential in improving performance. I see a lot of projects claiming outstanding performance like this one https://www.infoq.com/news/2020/10/markdown-wasm-fast-parser. WebAssembly inevitable in mobile browsers since more and more web apps / sites will use it. It has to have decent performance. The same can be done in Hermes. No problems with compilation issues on different platforms. Potential to interact / exploit improvements from WASI infrastructure. |
@likern whether Hermes should be able to execute Web Assembly is a different question. I agree that Wasm support in Hermes will be useful - it is just a matter of us prioritizing it and getting the work done. |
@likern just to confirm, by "WebAssembly support" you mean Hermes VM can (add a Wasm VM to) take Wasm bytecode as input and execute it along with JS (like any other web browsers), right?
The original question however, was phrased more like "compiling JavaScript to Wasm bytecode" (like AssemblyScript to the extreme), especially regarding the context of this issue was "compiling JS to native code", which is a completely different thing. |
In Javascript, I think the only time we can't infer type is when dealing with side effects ( FP term). There are only handful of ways to deal with real world, such as JSI and |
I decided to not create new issue to ask this question. Just wanted to bring in some attention to this topic since I couldn't find any information / plans regarding WebAssembly. And issue with "Native / WebAssembly" could fit. Yes, I meant that Hermes could run WebAssembly modules like web browsers do. But I didn't mean to compile JavaScript to WebAssembly. I meant compile C / C++ / Rust to WebAssembly and run it. In React Native world there is some very important big pain points related to performance issues. It's react-native-svg which implements SVG spec and allows to create complex and rich UI components. There's no alternative solutions to it. But this projects uses old Native Modules with bridge. For more complex things rendering becomes very slow. And it will no be rewritten using C++ / JSI / TurboModules anytime soon. So new upcoming RN architecture won't help. If we could take some C++ SVG rendering library, compile it to WebAssembly (I think it should be able to interact with JavaScript seemlessly) and run - that could eliminate most struggles and open up new possibilities for React Native apps. Ideally is to take Skia (which internally uses Flutter as rendering engine for their components). The same problems with react-native-storage which uses SQLite database. If we could take C++ drivers, compile to WebAssembly - that could eliminate Java / JNI part and all serialisation between C -> Java -> JavaScript. On Reddit comments someone said using JSI is much faster. Now we have to use Java https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase. There is others important libraries that might benefit from this. |
@likern Wasm support is something that I would really like to do and have been thinking and planning about it (I have a pretty detailed design complete in my head). But we don't have a strong use case for it currently, so it is hard to prioritize working on it yet. |
@supercharger there have been many experiments to add static typing to JavaScript, to compile TypeScript to native, etc. Without getting in details about the viability of those, we are no longer talking about "compiling JavaScript to native", but about a new language with new syntax and new semantics (even if it looks similar to JavaScript). Everything would have to be re-written for that new language - you wouldn't be able to use any existing JavaScript modules. So, what would be the point? Other statically typed compiled languages already exist. The goal of Hermes is to improve specific use cases for existing code written in JavaScript. |
@tmikov There is a open source project "NectarJS" to compile JS to native. They claim that it doesn't increase the binary size. Just checking your thoughts on this project. |
@supercharger there are many projects that have attempted this, for example: https://github.com/tmikov/jscomp :-) I don't feel comfortable criticizing other OSS projects. Looks like a lot of work has gone into NectarJS and I certainly wish it success. You can make your own evaluation of whether its correctness, output size and runtime model meet your needs (for example the lack of garbage collector). I did look quickly into the code it generates and I don't think invalidates anything I said above. The binary size increases for sure. I also tried a couple of trivial tests and ran into correctness issues. |
@tmikov Thanks for answering the questions with patience. I hope this github issue helps others as well, with the same question about hermes. I am going to close this after 2 days of inactivity. |
Problem
Suboptimal performance compared to JIT ( only in certain conditions) and native/machine binaries
Discussion
Hermes compiles the code to Hermes VM. While It improves TTI, It is suboptimal to JIT ( only in certain conditions) and native/machine code. Alternatively,Javascript code can be compiled to native binary, and use a variant of memory management ( reference counting, etc).
Is there a plan to have Hermes target as native binary ( without VM)? Also, Can you answer following questions.
PS: I did extensive search ( issue search & google) on why hermes uses VM and couldn't find any reasoning.
The text was updated successfully, but these errors were encountered: