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?
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?
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:
Ruby (prior to 1.9):
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.
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.
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.
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.
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) :-)