8 ms·
PyPy.js: First Steps
- Hello71 13y ago> two orders or magnitude speed difference right now 1. I think you meant "of". 2. log(781250 / 877) is closer to 3 than 2.
- pudquick 13y agoHow does this compare to http://repl.it/ http://repl.it/ ? Anyone figured out how to get a comparable benchmark out of it without loading a full browser? The reason I ask is that http://repl.it/languages/Python http://repl.it/languages/Python loads quickly and can actually run in my iPhone 4S Mobile Safari. At 139 MB uncompressed currently, I'm not sure this new project will ever result in something that would let me write python code natively in a <script>. I know that he's currently running with node.js, so no browser required, but if this project is only ever going to be yet another desktop/server interpreter, I would be gobsmacked if it could remotely approach PyPy or CPython performance - even once they get JIT going.
- quacker 13y agorepl.it uses a version of CPython compiled with emscripten[1], so the version in the article should be similar in size. 1: https://github.com/replit/empythoned https://github.com/replit/empythoned
- pudquick 13y agoThis is incorrect. The article involves compilation of the PyPy interpreter (not CPython) into JS. This is why I asked about someone attempting a benchmark comparison between the two. Still, it's a fun project. Good luck to the author.
- quacker 13y agoThe quoted 139 MB includes the full Python standard library, which certainly accounts for a majority of that size. repl.it also compiles the entire Python standard library, so why should the two be significantly different in size?
- zeckalpha 13y agoThey are two different implementations of the standard library.
- quacker 13y agoThe PyPy project did not reimplement the entire Python standard library. The goal of PyPy is to provide a drop-in replacement for the canonical CPython interpreter. Right now, PyPy is (very) compatible with existing Python 2.7.3 code.[1] 1: http://pypy.org/compat.html http://pypy.org/compat.html - Standard library modules supported by PyPy. Note that large parts of python library are implemented in pure python, so they don't have to be listed there.
- zeckalpha 13y agoI didn't say the entire library was reimplemented, just that they are two different implementations.
- azakai 13y agorepl.it does not include the full standard library. repl.it uses dlopen to load python modules at runtime, which were compiled separately. pypy.js on the other hand does include the full standard library.
- pudquick 13y agoFor anyone following here at this point, I've downloaded the entirety of the repl.it python engine by using os.walk() on the root directory (/), causing my browser to download every .js, .py, etc. file it can find and store them locally, uncompressed, on my machine. It even amusingly found some .exe files hosted in the distutils directory. The entirety of the repl.it emscripten CPython project is 24MB, uncompressed. This includes the entire standard library that it ships with and all the '_underscore.so.js' emscripten compiled shared objects. Compressed via zip it's 4.7MB. For comparison, this is almost identical (within a few MB) to a clean install of python locally on my workstation, size-wise. I am assuming at this point that it's most if not all of the standard modules included at repl.it. (And for reference: The core CPython engine, translated minus modules, weighs in at 4.6MB uncompressed and 800KB compressed) Downloading the prebuilt PyPy project from http://pypy.org/download.html http://pypy.org/download.html I see that uncompressed the project is 55MB in size. Removing all .txt and pure .py files, I'm left with 37MB (and that's being generous) of 'code' files that potentially are being translated. And that's with shared objects - not a static compile - so there's possibly duplicated code in there that wouldn't be present in a single monolithic executable. I stand by my assertion that 139MB is significantly different in size and that the translation is what accounts for the majority of that size (84MB if I'm generous, 102MB if I'm slightly more realistic). As much as there may be a speed benefit, eventually, if everything works out here, the current size of the project definitely moved it out of the realm of anything I'd want to attempt loading into a browser.
- apendleton 13y agoPerhaps I'm missing something fundamental here, but my understanding of the way that JITs work is that they inspect a bunch of bytecode, then generate a bunch of machine code, then execute it. No Javascript interpreters are going to let you write executable code into a random chunk of memory and run it, so compiling a JIT with emscripten seems like a non-starter.
- ot 13y agoInstead of generating machine code, the (guest) JIT can generate optimized JS, possibly in the asm.js fragment. The host JIT can then JIT the generated JS into optimized machine code, thus the overhead could in principle be minimal. EDIT: If this seems too mind-bending, think that even machine code is not really machine code: the CPU actually JITs the "native" code (say, in the x86-64 ISA) into a "more native" code that is what is actually executed by the CPU (for Intel CPUs, these are "micro-ops"), and in doing that it uses a lot of compilation tricks (such as trace caches), including optimizations driven by runtime feedback (you can think of branch prediction this way). Of course Javascript is a much thicker abstraction, but conceptually it is not much dissimilar.
- jlongster 13y agoYep, exactly. The JIT backend would generate js (hopefully asm.js style code), which will be further optimized and executed by the js engine down to native code.
- azakai 13y agoVery correct, but a side note: asm.js might not be useful or necessary for this. asm.js makes more of a difference in large, hard to optimize codebases, and less in small amounts of code, because JS engines have been optimizing small amounts of code extremely well for a while now (using TraceMonkey, CrankShaft, DFG, IonMonkey, etc.). Also, asm.js code is structured in a way that makes it obvious the code will not change over time (it's in a closure, where functions cannot be modified), again, in order to make optimizing large projects easier. When JITing however you do want to add new code all the time. But this could work great without generating asm.js code. The VM itself is C code that can be compiled wholesale into asm.js (when the Lua VM was compiled that way it was quite fast, about 50% of native speed), and it would then JIT at runtime normal JS and call into that.
- spankalee 13y agoImplementing an interpreter on typed arrays is leaving a lot of the power of the dynamic OOP host untapped. Translating Python classes to JS objects like Skulpt is a much better approach.
- kevingadd 13y agoNot if you know anything about modern JS runtimes, it isn't. [1] https://github.com/sq/JSIL/wiki/JavaScript-Performance-For-Madmen https://github.com/sq/JSIL/wiki/JavaScript-Performance-For-M... [2] https://bugzilla.mozilla.org/show_bug.cgi?id=885526 https://bugzilla.mozilla.org/show_bug.cgi?id=885526
- spankalee 13y agoI'm not sure what your point is, but so far the asm.js samples that I've seen have not indicated that compiling a runtime for a dynamic language, including memory management, GC, and JIT, are anywhere near as fast as transpiling to JS, and there are tons of complications. lua.vm.js is running at 50% of Lua, not LuaJIT. Add to that that you can't touch the DOM from asm, and the ported VM basically has it's own heap and no way to collect cycles between Lua and JS and it's not a good solution. Much better to rely on the JS VM for memory management.
- kevingadd 13y agoTranspiled asm.js code beats the pants off non-asm.js code in almost every regard. Period. I have not seen a single case where code heavily leveraging the JS GC heap, etc. will outperform the typed array, virtual heap, etc. style even WITHOUT the benefit of asm.js's AOT compilation. It's possible, of course, but I've never seen it. And I certainly haven't found any way to achieve it with a compiler. If you have, let me know...
- rfk 13y agoThe RPython toolchain has another mode of operation, which outputs higher-level class-based code rather than low-level C-style code. They use this for a CLR backend, but it would be interesting to try implementing a JavaScript backend at that level and compare it to the lowlevel+emscripten approach. (This may have been tried in the past; in the post "10 years of PyPy" it's mentioned that there was once a JavaScript backend but it was removed because it was a horrible idea: http://morepypy.blogspot.com.au/2013/02/10-years-of-pypy.html http://morepypy.blogspot.com.au/2013/02/10-years-of-pypy.htm...)
- dangayle 13y agoA hearty +1 to anything that lets us legitimately run a different scripting language in a <script> tag
- jnbiche 13y agoIt's really worth looking into the recent project that transpiled the Lua VM into JavaScript, and which allows Lua to be used in the browser -- even to interact with the DOM. The size of the Lua VM in JS is under 200 kB, not much bigger than a large JavaScript library.
- dangayle 13y agoI've seen that. I need to learn Lua. I have a friend who uses it as the scripting layer on top of all his C work, and he says its the best setup he's ever tried.
- albertzeyer 13y agoReally interesting project! In a comment, I found out about another project ShedSkin which seems to be like RPython, i.e. it compiles a subset of Python to C++. https://code.google.com/p/shedskin/ https://code.google.com/p/shedskin/ http://shed-skin.blogspot.de/ http://shed-skin.blogspot.de/ https://news.ycombinator.com/item?id=6091123 https://news.ycombinator.com/item?id=6091123
- jnbiche 13y agoNumba is a fast Python compiler that uses LLVM as an intermediary. In fact, I just checked, and it has a switch to emit LLVM directly. Emscripten is an LLVM-to-JavaScript transpiler. Is there any way the two of those could be hooked up?
- kingkilr 13y agoNumba isn't a general purpose python compiler, it compiles a small subset of the Python language that targets numeric computations.
- jnbiche 13y agoYes, Numba isn't a general purpose compiler of Python -- sorry if I implied that. And to be clear, this isn't a Python runtime you'd compile to JS for the browser, this is something that could compile scientific/numeric Python into JS. However, it is exactly the type of code that Numba targets that would be the most interesting to port to JS. And it's quite simple to port such code in Numba; usually all that's required is some incantation involving 'jit' or 'autojit'. I mean, you're not going to be using tkinter or running Python networking modules on the browser, anyway. If you could compile some of the scientific and numeric Python that exists into JS, it would allow a lot of scientific computing to be distributed and run on the web, client-side, including most of the machine learning and NLP code that exists now in Python. From just an hour of research, it doesn't look like it would be very hard. But I only know enough about the two projects to be dangerous. At the very least, it's an interesting idea. EDIT: TO clarify, I'm referring to "distributed" as in distribute an asset (in this case a JS script) to a computer to be run, not distribute a work load.
- sleepingpills 13y agoThe problem with your suggestion is that scientific/numeric python tends to rely very heavily on numpy/scipy/pandas, most of which are in turn written in C/Fortran/Cython. Meaning, you could only funnel the glue code to JS, not the code that does the heavy lifting. You'd need to also port the above libraries to JS, which would be a pretty large undertaking. Finally, grid computing is not any easier in JS than in python, since python already has lots of bindings for the required tools (e.g. take a look at http://star.mit.edu/cluster/ http://star.mit.edu/cluster/ which even comes preinstalled on EC2 AMIs). Edit: I just noticed that you suggested using JS for distributed computing in lieu of python. Care to suggest a scenario where JS would be a better suited language? Why would I want to run scientific computing in browsers?
- hencq 13y agoWhile it's certainly an interesting project, I wonder how practical it is. All javascript engines have powerful JITs and it seems like a waste not to use them, but instead to implement your own interpreter. I think the approach taken by e.g. clojurescript or dart is more viable, where they compile to javascript and let the JIT do its magic.
- bayesianhorse 13y agoThe big problem with that approach and Python is Python's dynamic object model. It's really hard to completely emulate that completely in javascript, and by then it would probably not be that much cleaner, smaller or faster than CPython compiled to Javascript. Without the type system however, Python in the browser is next to useless in practice.
- azakai 13y agoAs mentioned in the link, the goal is to eventually use the JIT - the title does contain "First Steps" in it ;) No reason this approach cannot JIT into JS just like clojurescript and dart.
- hencq 13y agoIf I read it correctly, his goal is to use the PyPy JIT. So what he's doing is translating the PyPy JIT (which is created automatically from the interpreter written in RPython) into javascript. Because he's using emscripten this javascript code can be statically compiled by virtue of asm.js (in Firefox at least).
- azakai 13y agoYes, he plans to use the PyPy JIT, but it will generate code that is then JITed by the JS engine JIT. It doesn't require special static compilation to optimize small amounts of JITed code, all modern JS engines can do that extremely well. asm.js is not necessary there.
- __alexs 13y agoThis is an utterly ridiculous idea and I'm amazed it works at all, well done :) If the CPython API is so easy to get going on emscripten I wonder if anyone has tried using emscripten to compile Nuitka (http://nuitka.net/ http://nuitka.net/) output to Asm.js yet?
- jnbiche 13y agoWow, I'd not yet heard of Nuitka. Thanks for the reference...I'm very interesting in trying it out.
- slacka 13y ago"This is an utterly ridiculous idea and I'm amazed it works at all..." Yes, reminds me of the people that like to run NES emulators, inside of Dreamcast emulators, inside of their virtual PC running on a Mac. Yes it's impressive, but as the author admits running a VM inside of a VM results in a "two orders of magnitude" loss of performance.
- redler 13y agoQq