views:

497

answers:

5

They seem to share a lot of the same characteristics but as far as I can tell, Python 2.5 is faster than 1.8.7 by a lot.

Is there a deeper underlying reason behind this?

+13  A: 

One reason is Python's being compiled into bytecode which is then executed by a highly optimized VM. AFAIK Ruby doesn't work this way in 1.8 and earlier - but interprets the trees on the fly.

Think of it this way:

Python:

  1. Parse code into ASTs
  2. Convert ASTs into bytecode
  3. Run bytecode on a VM

Ruby (prior to 1.9):

  1. Parse code into ASTs
  2. Interpret the ASTs directly by recursive traversal

Without getting too much into detail, step 2 in the old Ruby has a lot of repetitions because it has to "understand" the ASTs each time it sees them (which, in an inner loop is a lot). Python "understands" the ASTs only once, and then the VM runs the bytecode as fast as it can (which isn't different in principle from the way the Java and .NET VMs work).

Ruby 1.9 moved to YARV, which is also a VM-based approach. Ruby 1.9 is faster than 1.8. Here's a quote from the creator of YARV, Koichi Sasada:

At first, YARV is simple stack machine which run pseudo sequential instructions. Old interpreter (matzruby) traverses abstract syntax tree (AST) naively. Obviously it's slow. YARV compile that AST to YARV bytecode and run it.

An interesting point to note is that the Python VM is also stack based, just like YARV.

Eli Bendersky
Are there actually non-stack based VMs?
Helper Method
@Helper: of course. Parrot is register-based, for example
Eli Bendersky
@Helper Method: the Dalvik VM on Android, the Lua VM since 5.0, the tinypy Python VM, the tinyrb and RubyGoLightly Ruby VMs, and, as @Eli Bendersky already mentioned, the Parrot VM are just a few examples of register-based VMs.
Jörg W Mittag
@Helper Method: Oh, and how could I forget the Nitro ECMAScript VM which is part of JavaScriptCore and thus part of both OSX and Safari.
Jörg W Mittag
+4  A: 

Because Ruby 1.8 was not really designed with performance in mind, while Python was more optimized. In particular, Ruby 1.8 did real interpretation rather than compiling for a virtual machine like most languages these days. Ruby 1.9 (with the YARV VM) is about as fast as Python 3 (maybe a little bit slower, but much closer), and other implementations are even faster.

Chuck
Ruby 1.9 is 2x slower than Python, 1.8 was 4x slower, see below http://stackoverflow.com/questions/3252568#3262523
Nas Banov
@Nas Banov: The question was not specifically about performance in the Alioth game, so presenting that as *the* canonical answer is deceptive at best. 2x for a set of highly specialized benchmarks (which even call themselves "flawed") is pretty close.
Chuck
@Chuck: I don't have any other **reliable** source for comparison. The *Language Shootout* surely is more reliable and less biased than either me or you alone, since multiple people contribute - it is open and if you think that some of the code does not do justice to Ruby, you can fix it and improve the result... as have people before you - just like Wikipedia is built.
Nas Banov
@Chuck: Nas Banov doesn't seem to be presenting the benchmarks game as "the canonical answer", just as something more substantial than 'it's about as fast because I say it's about as fast'.
igouy
+15  A: 

Nothing deep, I am pretty sure -- it's strictly a matter of implementation choices and maturity. Python was quite a bit slower in many aspects not so long ago, after all! Consider for example:

$ py24 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 10.8 usec per loop
$ py25 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 9.83 usec per loop
$ py26 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 8.12 usec per loop
$ py27 -mtimeit '[i+i for i in xrange(55)]'
100000 loops, best of 3: 6.35 usec per loop

Yep, all on the same machine (Macbook Pro, 2.4 GHz Intel Core 2 Duo, OSX 10.5), all "official" Mac releases from python.org (latest one of each x in the 2.x series). I have no 2.3 around to check, but I'd expect it to be a wee bit slower than 2.4.

This is just the kinds of speed-up that a lot of loving, painstaking work can achieve among successive releases of pretty much the same underlying architecture. Not as flashy as adding feechurz, but often vastly more useful in the real world!-)

I'm pretty sure, therefore, that Ruby can also stabilize on a sound, performance-robust underlying architecture, then start getting a steady stream of under-the-hood performance tweaks over the years to get (e.g.) the 40% or so further improvement we observe here has been happening in (at least some parts of) Python in the last few years.

Alex Martelli
A: 

More people have been working on Python development for more years, so more optimization has been done. The languages are similarly flexible and expressive, so their performance should converge as all the good optimization ideas get used in both. As noted above, Ruby 1.9 substantially narrows the performance gap with Python.

Russell Borogove
+2  A: 

I read the answers and I see most people are saying "oh you should not compare to Ruby 1.8, you should go with 1.9, it's much faster". Well ok, why not just look at some benchmarks?

So here is how Ruby 1.9 (YARV) fares against Ruby 1.8 (MRI): http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=ruby

And here is how Ruby 1.9 compares to Python 2.x: http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=yarv&lang2=python

To recap, Ruby 1.9 is about 2x faster than Ruby 1.8 - but still is slower - 2x slower - than Python.


PS. I guess I need to clarify after Chuck's objections: I don't see the Computer Language Shootout as the definitive answer to the questions of Life, the Universe and Everything. Far from it. I would be glad to be referred to other objective sources.

I would also be glad to hear informal/subjective results from people here on S/O, provided they have participated in over 50 discussions on Python or Ruby and their Ruby/Python bias is within +/-5dB (Ruby/Python Ratio calculated as RPR=10*log10(numTags('Ruby')/numTags('Python')) dB; thus for user Chuck that would be 10*log10(225/13) = 12dB, mine is -10 - we both cannot be relied on unbiased opinion) :-)

Nas Banov
The benchmarks are interesting, but you read too much into them. You mean "Ruby runs a handful of very unusual programs about half as fast as Python." The Alioth shootout game is useful for getting a rough idea of the characteristics of different languages, but they're hardly good enough to give a precise indication like "Ruby 1.9 is 2x slower than Python" as though it's just the gospel truth and that's what you'll see if your program if you use it. I believe Ruby 1.9 is still slower than Python, but relying solely on a relatively small difference in the shootout game is a flawed methodology.
Chuck
@Chuck - "about 2x faster" and "2x slower" seem like they are presented by Nas Banov as approximations, not "a precise indication" as you try to suggest.
igouy