As I understand, the cause of the speed difference between compiled languages and python is, that the first compiles code all way to the native machine's code, whereas python compiles to python bytecode, to be interpreted by the PVM. I see that this way python codes can be used on multiple operation system (at least in most cases), however I do not understand, why is not there an additional (and optional) compiler for python, which compiles the same way as traditional compilers. This would leave to the programmer to chose, which is more important to them; multiplatform executability or performance on native machine. In general; why are not there any languages which could be behave both as compiled and interpreted?
-
5There is. Haskell can also behave as compiled or interpreted through GHCI– toasted_flakesCommented Jun 7, 2014 at 10:00
-
C++ also have interpreters. And probably tons of other languages have both implementations.– ClaudioCommented Jun 7, 2014 at 11:29
-
2Actually, by choosing IronPythong (ironpython.net) and compile the produced IL code by using "ngen" (msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx) there is a way to compile Python to native machine code. Not that I had tested that tool chain.– Doc BrownCommented Jun 7, 2014 at 13:00
-
12One can write Python-to-native compilers. They just aren't very interesting because they don't actually improve performance by any significant margin, unless they actually implement a language that looks like Python but is far more restricted. I previously explained elsewhere why.– user7043Commented Jun 7, 2014 at 17:51
3 Answers
No. The reason why there are speed differences between languages like Python and C++ is because statically-typed languages give the compiler tons of information about the structure of the program and its data which allows it to optimize both computations and memory access. Because C++ knows that variable is of type int, it can determine the optimal way to manipulate that variable even before the program is run. In Python on the other hand, the runtime doesn't know what value is in a variable right until the line is reached by the interpreter. This is extremely important for structures, where in C++, the compiler can easily tell the size of the structure and every location of its fields within memory during compilation. This gives it huge power in predicting how the data might be used and lets it optimize according to those predictions. No such thing is possible for languages like Python.
To effectively compile languages like Python you would need to:
- Ensure that the structure of data is static during the execution of the program. This is problematic because Python has eval and metaclasses. Both which make it possible to change the structure of the program based on the input of the program. This is one of the things that give Python such expressive power.
- Infer the types of all variables, structures and classes from the source code itself. While it is possible to some degree, the static type system and algorithm would be so complex it would be almost impossible to implement in a usable way. You could do it for a subset of the language, but definitely not for the whole set of language features.
-
12It's worth noting that this does make the problem hard, but not impossible. sbcl compiles Common Lisp which also is dynamic, has
eval
, and a bunch of other things to make compiler writers sad. It's not to the level of gcc, but it's certainly faster than CPython's interpreter. Commented Jun 7, 2014 at 16:44 -
3@jozefg I said effectively compile. Not just compile. Python too has it's Cython compiler which produces native code. The point is those compilers ca'nt do even fraction of optimizations that compilers for statically-typed languages can. And when you compare performance, compare it to compiled C++ and not interpreted Python.– EuphoricCommented Jun 7, 2014 at 16:47
-
4Well actually, you'd be surprised what sbcl can do. The benchmarks game shows it running as fast as Java, nearly as fast as GHC, and within 1x to 10x of C. It's not slow by any standards. Yes, dynamic types inhibit compilation to some extent, but not so much as you seem to think. Commented Jun 7, 2014 at 16:52
-
@jozefg this depends on the nature of the application and the implementation. If I were to code in C++ using Python philosophy (e.g. use lists for just about anything), the performance of my C++ program would be terrible (or, conversely, Python would be competitive). A proper static implementation may have significant performance benefits over a dynamic one, depending on the nature of the program (for IO bound programs it won't matter, for instance). Note that performance benefits need not be time: memory requirements are also much higher for dynamicly typed languages. Commented Jul 30, 2014 at 14:07
-
5Comparing the speed of interpreted python to compiled python is interesting in itself. Stop saying "use C++". Perhaps you already have the code written in Python. Perhaps the code is easier to write in python. Who cares. What I do care about is a 1.5x speed up (whatever it is). That can make a huge difference. Commented Nov 8, 2014 at 10:30
Two concepts might help us understand better why Python compiled to native machine code "may" not run as fast as compiled C or other commonly compiled languages. They are called early binding and late binding.
I should begin by saying I am not a Python expert, and I came to this site by accident. But I like this site.
As mentioned in another response here, the C++ compiler can know a lot about the program and make decisions about which operations to use for specific data structures. As an example if two integer variables need to be added together, the compiler knows they are native integers, 32 bits wide for example and it can add them together with one "ADD" instruction. So it compiles the ADD instruction into the code. It's locked in and can't be changed while the program is running. That is early binding.
On the other hand in a language like Python we could expect the program to throw different types of data together in complex ways. Now the compiler does not know if our 2 variables are integers, floats, strings or lists. So it has to compile code that determines that information at run time and select the correct operation while the program is running. This is late binding and we can understand that there will be a performance hit for doing that extra work while the program is running. It is the price you pay for keeping those options open in a language like Python but it provides maximum run-time flexibility.
I think it has more to do with the Python specifics itself, the same reason you can't compile C# to machine code. Language specifics would actually render your programs buggy even if it were possible due to the nature of the language. Why not just learn the C language? Its much easier than C++ and slightly advanced than Python but still approachable.
-
6C# can go directly to machine code: Common Intermediate Language: Ahead of Time compilation - "CLI-compatible execution environments also come with the option to do an Ahead-of-time compilation (AOT) of an assembly to make it execute faster by removing the JIT process at runtime. In the .NET Framework there is a special tool called the Native Image Generator (NGEN) that performs the AOT. In Mono there is also an option to do an AOT."– user40980Commented Nov 11, 2015 at 20:21