简体   繁体   中英

Why is Python faster than Ruby?

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?

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 (eg) the 40% or so further improvement we observe here has been happening in (at least some parts of) Python in the last few years.

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.

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.

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) :-)

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.

It depends on the implementation. Crystal is basically C compiled Ruby that can even call C libraries. Then you also have Elixir on the Beam side and let's not forget the Java and C# counterparts. But yes, Ruby, the defacto standard, is indeed slower than Python and is also aimed at web development.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM