82

This is just a wondering I had while reading about interpreted and compiled languages.

Ruby is no doubt an interpreted language since the source code is processed by an interpreter at the point of execution.
On the contrary C is a compiled language, as one have to compile the source code first according to the machine and then execute. This results is much faster execution.

Now coming to Python:

  • A python code (somefile.py) when imported creates a file (somefile.pyc) in the same directory. Let us say the import is done in a python shell or django module. After the import I change the code a bit and execute the imported functions again to find that it is still running the old code. This suggests that *.pyc files are compiled python files similar to executable created after compilation of a C file, though I can't execute *.pyc file directly.
  • When the python file (somefile.py) is executed directly ( ./somefile.py or python somefile.py ) no .pyc file is created and the code is executed as is indicating interpreted behavior.

These suggest that a python code is compiled every time it is imported in a new process to create a .pyc while it is interpreted when directly executed.

So which type of language should I consider it as? Interpreted or Compiled? And how does its efficiency compare to interpreted and compiled languages?

According to wiki's Interpreted Languages page, it is listed as a language compiled to Virtual Machine Code, what is meant by that?

10
  • 1
    When is there doubt as to whether Ruby is an interpreted language? When it's compiled. :) macruby.org
    – mipadi
    Dec 8, 2010 at 14:34
  • 8
    It is worth noting that no modern language is interpreted in the strict sense. Virtually all of them compile to bytecode. Dec 8, 2010 at 14:59
  • @Winston Ewert: bravo! Applesoft Basic (in 1980's) was byte-code compiled. "modern" in this case, means every interpreted language in living memory with the only possible exception being some rudimentary Dartmouth Basic implementations.
    – S.Lott
    Dec 8, 2010 at 18:13
  • 6
    >> On the contrary C is a compiled language << root.cern.ch/drupal/content/cint
    – igouy
    Dec 11, 2010 at 18:34
  • 3
    @S.Lott: Calling the tokenization process that Applesoft and '80s BASIC interpreters did "bytecode compilation" is more than a little disingenuous. Yes, the program code entered by the user was stored in memory in a compressed form, one byte per reserved word, but nothing was done beyond that until you typed RUN. It was as if you had a compiler that did the lexing step and then output a stream of tokens that had to be reparsed every time the program was run. Not at all like modern bytecode compilation as done by, say, javac, which encompasses lexing, parsing, and optimization. Jul 8, 2013 at 22:30

5 Answers 5

87

It's worth noting that languages are not interpreted or compiled, but rather language implementations either interpret or compile code. You noted that Ruby is an "interpreted language", but you can compile Ruby à la MacRuby, so it's not always an interpreted language.

Pretty much every Python implementation consists of an interpreter (rather than a compiler). The .pyc files you see are byte code for the Python virtual machine (similar to Java's .class files). They are not the same as the machine code generated by a C compiler for a native machine architecture. Some Python implementations, however, do consist of a just-in-time compiler that will compile Python byte code into native machine code.

(I say "pretty much every" because I don't know of any native machine compilers for Python, but I don't want to claim that none exist anywhere.)

7
  • Depending on your definition, native machine compilers for Python exist. Some only compile a subset of python. Others implement all of python but use the python API to actually perform the operations which it cannot perform in C. Dec 8, 2010 at 15:02
  • I think you're actually describing that Python is either what I would call 'semi-compiled', or can actually be full compiled. By semi-compiled I mean that since it is usually compiled to the 'intermediate language' .pyc file that is used by the Python Virtual Machine, it is usually being run from this 'semi-compiled' form, that generally makes code faster than plain run-time interpretation of interpreted code. Interestingly, semi-compiled code can sometimes be faster than natively compiled code (e.g. C# is generally faster than C++). Jun 25, 2015 at 4:16
  • 6
    Cython compiles Python code to C so that it can be compiled as a shared object.
    – greyfade
    Oct 23, 2015 at 6:04
  • Distinguishing byte code and machine code in this fashion is pretty arbitrary. Java is compiled: the javac compiler produces class files containing low level instructions that may be executed, either in a virtual machine (eg hotspot) or directly by hardware (e.g. on ARM processors with the Jazelle extension). As far as I know, there is no technical reason a similar processor architecture couldn't be designed to directly execute python vm instructions.
    – Jules
    Oct 23, 2015 at 12:11
  • @Jules Coincidentally, Jython code is actually compiled in to .class files which I believe are reused until you modify the py source.
    – JimmyJames
    Aug 18, 2017 at 16:41
36

Python will fall under byte code interpreted. .py source code is first compiled to byte code as .pyc. This byte code can be interpreted (official CPython), or JIT compiled (PyPy). Python source code (.py) can be compiled to different byte code also like IronPython (.Net) or Jython (JVM). There are multiple implementations of Python language. The official one is a byte code interpreted one. There are byte code JIT compiled implementations too.

For speed comparisons of various implementations of languages you can try here.

12
  • thanx for the info.According to the benchmarks the performance of python is way down!
    – crodjer
    Dec 8, 2010 at 8:18
  • 1
    The link I gave very clearly states these are flawed benchmarks of language implementations. Python should not be your choice of language if you worry too much about execution performance. If you still want to compare, compare similar languages. Byte code interpreted official CPython is comparable to or faster than JIT compiled Ruby.
    – aufather
    Dec 8, 2010 at 14:42
  • 1
    @jase21 - "My plans for 2006 are to port the techniques implemented in Psyco to PyPy. PyPy will allow us to build a more flexible JIT specializer, easier to experiment with, and without the overhead of having to keep in sync with the evolutions of the Python language." psyco.sourceforge.net/introduction.html
    – igouy
    Dec 11, 2010 at 18:25
  • 1
    @jase21 - "makes python codes run faster than C counter parts" - Are we supposed to just take your word for that?
    – igouy
    Dec 11, 2010 at 18:28
  • 3
    Link in the answer is broken.
    – Basilevs
    Jan 2, 2016 at 5:09
12

Compiled vs. interpreted can be helpful in some contexts, but when applied in a technical sense, it is a false dichotomy.

A compiler (in the broadest sense) is a translator. It translates program A to program B and for future execution it using a machine M.

An interpreter (in the broadest sense) is an executor. It is a machine M that executes program A. Though we typically exclude from this definitions physical machines (or non-physical machines that act just like physical ones). But from theoretic perspective, that distinction is somewhat arbitrary.


For example, take re.compile. It "compiles" a regex to an intermediate form, and that intermediate form is interpreted/evaluated/executed.


In the end, it depends on what level abstraction you are talking about, and what you care about. People say "compiled" or "interpreted" as broad descriptions of the most interesting parts of the process, but really most every program is compiled (translated) and interpreted (executed) in one way or another.

CPython (the most popular implementation of the Python language) is mostly interesting for executing code. So CPython would typically be described as interpreted. Though this is a loose label.

7

Virtual Machine Code is a more compact version of the original source code (byte code). It still needs to be interpreted by a virtual machine, since it is no machine code. It's easier and faster to parse than the original code written by a human being, though.

Some virtual machines generate machine code while interpreting the virtual machine code for the first time (just in time compilation - JIT). The following invocations will use this machine code directly, which leads to faster execution.

As far as i know Ruby >= 1.9 uses a virtual machine like Python too.

5

The Python runtime runs custom object code(byte code) on a virtual machine.

The compilation process converts source code to object code.

To speed things up, the object code (or byte code, if you prefer) is stored on disk, so it can be reused the next time the program is run.

Not the answer you're looking for? Browse other questions tagged or ask your own question.