
PyPy.js: Now faster than CPython - ot
https://rfk.id.au/blog/entry/pypy-js-faster-than-cpython/
======
cft
I felt it was a grave mistake for Python to direct the community effort into
backwards incomparable Python 3, rather than on focusing on the speed (and
better profiling instrumentation) of Python 2 (perhaps adding a standard JIT
compiler). As a result, had our company started now, we would have written our
Twisted server in C or Go instead of Python like we did.

~~~
frik
Meanwhile, refactored PHP makes Wordpress 20% faster.
[http://news.php.net/php.internals/73888](http://news.php.net/php.internals/73888)
, [https://wiki.php.net/phpng](https://wiki.php.net/phpng) and
[https://news.ycombinator.com/item?id=7699322](https://news.ycombinator.com/item?id=7699322)

HHVM and now PHP 5.7-dev, both with JIT - the future of PHP looks bright.

Starting a new project, we would choose PHP, Node.js or Go according to the
requirements.

~~~
mantrax5
Yeah, so refactored PHP makes a PHP app 20% faster.

But you might actually not like to hear Node's V8 engine is between 50 and 150
_times_ faster than PHP in synthetic benchmarks, and about 20 _times_ faster
in more diversified applications (as long as they don't sit an eternity
blocking waiting on a DB call which is the way people did web apps 10 years
ago). That's 2000% faster than PHP, just so we use the same units here.

I'm very happy PHP is getting faster and all, but just don't juxtapose it next
to JS engines (which the article talks about), let alone something more
serious like the JVM, because the "bright future" of PHP starts looking quite
dim in comparison.

~~~
frik
It depends, for things like Web Sockets Node.js is really good. But for other
things, HHVM (Facebook's HipHop JIT) and the new PHP 5.7 dev with JIT are
really fast.

Check out an independent benchmark for comparision:
[http://www.techempower.com/benchmarks/#section=data-r9&hw=i7...](http://www.techempower.com/benchmarks/#section=data-r9&hw=i7&test=update)

------
tdees40
I just ran the same test and got 80.8K pystones/sec (CPython) vs. 234.3K/sec
(PyPy.js - Chrome, after a few warm-ups), so yeah, wow.

------
vanderZwan
I am colourblind and have problems with your choice of red and green for
graphs.

~~~
icebraining
Not that it shouldn't be fixed, but have you tried [http://www.ryobi-
sol.co.jp/visolve/en/](http://www.ryobi-sol.co.jp/visolve/en/) ?

~~~
vanderZwan
I have on Windows, didn't really "stick". But I'll try it out on mobile
though, might be more useful as a form of augmented reality, thanks!

------
panarky
I get 157K/sec in the terminal and 309K/sec in Chrome.

As the article says, Chrome's performance shows wide variation, even after JIT
warmup. It's ranging from 50K/sec to 320K/sec. Bizarre.

~~~
azakai
JITs are great but can be unpredictable, that's probably the cause. As
mentioned in the article, JITs vs AOT have upsides and downsides.

~~~
steveklabnik
Doesn't Chrome specifically _not_ optimize asm.js, as well? Wonder if that has
anything to do with it.

~~~
zurn
It doesn't special case the asm.js JS subset same way as Firefox does, but V8
guys are paying attention to optimizing asm.js-style code.

------
knackernews
So for how long will the python community pretend that performance isn't a
problem? (Inb4 "all the intensive parts of my app are written in C",
_addendum: "my app isn't CPU bound", "we have libraries written in C"_)

The interpreters (esp CPython) need some hardcore engineering (like how
javascript got V8). Languages that have the same theoretical performance
limits of Python are now blowing it out of the water.

The stories about teams that were able to go down from N servers to 1 server
by switching from Python to Go/Scala/node.js will hurt it in the long run.

~~~
TillE
Lots of people use Python for tasks that are not CPU-bound. Scalable web-
whatever and scientific computing aren't the whole world.

~~~
apendleton
Even scalable web-whatever is often IO-bound... of my several apps in
production, there's only one where CPU is a serious concern, and I run that
one on PyPy. cPython is fine for the others.

~~~
stcredzero
I'll go so far as to say that we haven't done enough with making things fast
on multicore processors _except_ with IO-bound tasks. The current architecture
of multicore processors stinks for achieving anything but the "embarrassingly
parallel."

------
garindra
In the browser environment, people usually use quite a few inline anonymous
functions. Javascript is great at this since you can define full-blown
anonymous functions anywhere.

Python, on the other hand, is definitely one of the worst at this. You can
only create one-line, single-expression anonymous function with its lambda
keyword. Of all the languages you want to convert to JS so that it runs on the
browser, Python is probably the last.

~~~
zo1
I really don't understand this obsession with anonymous functions. If you're
doing anything longer than one line, there is absolutely no reason why you
should be sticking the entire function definition as a parameter.

I've had great usage from Javascript where I have separate functions with
proper names and formatting, and then pass a reference to them into the code
that asks for them.

Can someone please enlighten me about this whole anonymous functions thing
that Javascript seems to have popularized? What are some of the pro's of using
it over regular named/defined functions that sit by themselves and are
_reusable_.

~~~
hajile
I suggest you read SICP and gain an appreciation for higher-order functions.
Once you do, you will probably have answered your own question.
[http://mitpress.mit.edu/sicp/](http://mitpress.mit.edu/sicp/)

~~~
darkarmani
Doesn't that section use lambda for anonymous functions?
[http://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-12.html...](http://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-12.html#%_sec_1.3.2)

The OP is complaining about lambda functions in Python.

~~~
hajile
In python, it would be proper to say that ALL functions are lambdas except
that some/most of those lambdas are assigned to variables via syntactic sugar
(this is made very plain in sicp which is the main reason for suggesting
it).The only thing different about python vs most other languages is guido
refusing to implement multi-line lambdas.

As to any complaint, lambdas exist in python (that is, are made accessible to
the programmer) for the exact reason python also has a for loop in addition to
a while loop -- because they make things easier and more maintainable.

    
    
      def myApplyAdd(func, x):
        return lambda y: func(x+y)
    
      applyAddInst = myApplyAdd(lambda z: z*2, 20)
      applyAddInst(3) #output 26
    

becomes much less maintainable without lambdas and pollutes the scope with
unnecessary variables you must then keep track of

    
    
      def myApplyAdd(func, x):
        def innerAdd (y):
          return func(x + y)
        return innerAdd
    
      def mulByTwo(x):
        return x*2
    
      applyAddInstance = myApplyAdd(mulByTwo, 20)
      applyAddInst(3) #output 26
    

I would also note that list comprehensions make heavy use of lambdas. For
example, the following is actually using a for loop and calling

    
    
      lambda i: i**2
    

each each iteration

    
    
      result = [ i**2 for i in range(3, 30) ]

~~~
zo1
_" In python, it would be proper to say that ALL functions are lambdas except
that some/most of those lambdas are assigned to variables via syntactic
sugar"_

If a function is "assigned to a variable" then it's no longer a lambda,
because it's bound to an identifier. But I suppose the lines are a tad
blurred.

~~~
hajile
While I agree that the function "has a name", the function is still anonymous
in the sense that pointers don't have types, only values have types. As a side
effect of converting church's model to Turing's model, all "unnamed" lambda
functions are given one-time symbols as are all anonymous numbers, arrays,
classes, objects, etc.

    
    
      x = lambda x: x+x #a lambda, but has a named pointer
      x = 5
    

lambda is still in memory (until garbage collection), but it no longer has a
pointer to it.

    
    
      def x(y):
        return y+y
      
      x = 5 #the "named" function above is now without a pointer
    

A little off-topic (but answers your previous question and perhaps looks a
little deeper into lambdas), but let's take a quick look at javascript. JS
developers use lambda functions both because lexical closures don't pollute
the global namespace, they offer modules and alternatives to prototypal
objects, and because the language tends to make heavy use of callbacks (which
demonstrate the bad side of lambda functions). JS also only makes subtle
differences between lambdas and named functions.

    
    
      //lambda expression
      var x = function (){};
    
      //named function
      function x() {}
    
      //named lambda expression
      var x = function x() {};
    
      //self-executing lambda (returns 5)
      (function (x) {return x;}(5));
    

note that this would be a self-executing lambda in python

    
    
      (lambda x: x)(5)
    

basic module pattern using self-executing lambda

    
    
      my_module = (function (self) {
        "use strict"
        self = self || {};
    
        //private
        //pretty much inaccessible to the outside scope
        var privateVar = 5;
        //lambda expression again
        var privateFunc = function () {};
    
        //public
        self.publicVar = 5;
        self.publicFunc = function () {};
        self.getPrivateVar = function () {
          return privateVar;
        };
    
        return self;
      }(my_module));
    
      my_module.publicVar = 8;
      my_module.publicFunc();
      my_module.getPrivateVar();
    

This is where too many lambdas becomes a problem. Judicious use of naming
(even though they're only used once) makes things more legible.

    
    
      func1(function () {
        func2(function () {
          func3(function () {
            func4(function () {
          })
        })
      })

------
coldcode
Does this work at all in Safari? Is Safari's crappy performance of native->js
ever going to catch up to FF and Chrome?

~~~
azakai
Yes, Safari has been working on an LLVM-based JIT called FTL. It now
outperforms v8 on almost all asm.js benchmarks,

[http://arewefastyet.com/#machine=12&view=breakdown&suite=asm...](http://arewefastyet.com/#machine=12&view=breakdown&suite=asmjs-
apps)

That's not in release versions of Safari yet, it was just enabled on trunk.
But it will make Safari very competitive once more.

~~~
stcredzero
What if LLVM based JITs with NaCL style security were available in all
browsers except IE? (I'm just assuming Microsoft will drag their heels.) Then
an LLVM IR based bytecode could become a standard bytecode for browsers.

~~~
hajile
I believe that in many ways, this would be ideal. Not only could any language
be used (the implementers being responsible for interfacing with the browser
API), but the LLVM pseudo-asm could be pre-optimized saving the browser a lot
of work.

In the meantime, browsers would still be free to compete based on their JIT
implementations.

With rust and by proxy, Mozilla/Samsung's experimental Servo layout engine
targeting the LLVM, I can also see potential synergy in this situation.

------
camus2
Still trying to find a suitable "python to js compiler written in js that runs
in the browser" project.PyPy.js is unfortunatly too big and all the other
projects i found are either written in python or dont pass the browserify
step.I need a transpiler that runs in the browser.

------
omaranto
It's not faster on my computer, a 32bit netbook with an Intel Atom N450 chip
(all scores average of five warm runs):

    
    
        CPython 2.7.5:  27032
        PyPy.js:        20103
        PyPy 2.0.2:    444011
    

I ran PyPy.js on Firefox 29.

------
bayesianhorse
Python in the browser so far is a big disappointment. I still find it a lot
easier to just split frontend and backend development. In the future, PyPy.js
might become a viable alternative for big browser applications.

------
zo1
Am I the only one that considers the title of this very "bait"-y? I mean, if
you go on and read the article, it clearly shows that native PyPy is leaps and
bounds faster than the JS version. So in essence, it re-iterates what most of
us already know... That the PyPy implementation is much faster than the
standard CPython one. It's just now we get to "prove" it in JS as well, as if
it's some "suck it, python users" flaunt.

On a side note: To the PyPy.js authors/devs, great job! Looking forward to
playing around with this.

~~~
PetitPrince
According to the author, it is deliberately bait-y:

    
    
        OK OK, I couldn't resist that title but it probably goes a bit far. Let me try for
        a little more nuance:
            PyPy.js: Now faster than CPython, on a single carefully-tuned benchmark,
            after JIT warmup.

