I read that some constructs of Python are more efficient because they are compiled in C.
That's not true.
First off, there is nothing in the specification of the Python language that requires that certain functions have to be implemented in a certain language. A Python implementor can choose to implement any function and language construct anyway he wants. For example, in Jython, those functions are implemented in Java, not in C. In IronPython, they are implemented in C#. In PyPy, they might be implemented in RPython or just in Python. In Pynie, they are probably implemented in Python.
Seondly, there is nothing in the specification of the C language that says that it must be compiled. There are interpreters for C.
Thirdly, just because it is in C doesn't mean it's fast. There are C compilers out there which produce really terrible code, and there are pretty fast Python implementations.
And fourth, even if the function implemented in C is blazingly fast, that doesn't necessarily translate into faster execution speed of the overall program. Optimizations typically don't work across languages. For example, the optimizer can't inline the call to map into your program, because your program is written in Python but map is written in C. But inlining is pretty much the foundation of all optimizations, because inlining (and loop unrolling) give nice long straight paths of code without branches or calls, which is what optimizers love.
It's generally interpreted,
Actually, all currently existing Python implementations always compile Python code, they never interpret it.
Why not just compile the whole thing?
That's a good question! Writing everything in the same language has many advantages, some of which I outlined above. (Another one is that it's easier to find collaborators who know one language than two.)
If everything is written in the same language, then performance improvements to that language get multiplied throughout the whole system. If everything is written in C, then making the Python 10 times faster isn't going to speed up your program much, because most of the code isn't Python. Sure, the code you wrote is running 10 times faster, but that code mostly consists of calls to C functions which have the same speed as before.
But if everything is written in Python, then making Python faster will have a ripple effect: the primitive types get faster, the datastructures built on top of those primitive types get faster, the algorithms using those datastructures get faster, the modules using those algorithms get faster and so on.
Answer from Jörg W Mittag on Stack Exchangeif python is going to be converted to C anyways why not give the generated C code to the user and then the user can compile it and have better performance?
Is there anything to translate Python to C code?
Convert Python program to C/C++ code? - Stack Overflow
Is Python interpreted, or compiled, or both? - Stack Overflow
Are there any libraries that can easily convert Python to C/C#/or C++? Ones where a person doesn't have to "calibrate" it, just, pip install library and then they can have their Python code in C,C#,or C++?
What types of Python code can be converted to C?
Is the Python to C converter free?
Can I also convert C back to Python?
I read that some constructs of Python are more efficient because they are compiled in C.
That's not true.
First off, there is nothing in the specification of the Python language that requires that certain functions have to be implemented in a certain language. A Python implementor can choose to implement any function and language construct anyway he wants. For example, in Jython, those functions are implemented in Java, not in C. In IronPython, they are implemented in C#. In PyPy, they might be implemented in RPython or just in Python. In Pynie, they are probably implemented in Python.
Seondly, there is nothing in the specification of the C language that says that it must be compiled. There are interpreters for C.
Thirdly, just because it is in C doesn't mean it's fast. There are C compilers out there which produce really terrible code, and there are pretty fast Python implementations.
And fourth, even if the function implemented in C is blazingly fast, that doesn't necessarily translate into faster execution speed of the overall program. Optimizations typically don't work across languages. For example, the optimizer can't inline the call to map into your program, because your program is written in Python but map is written in C. But inlining is pretty much the foundation of all optimizations, because inlining (and loop unrolling) give nice long straight paths of code without branches or calls, which is what optimizers love.
It's generally interpreted,
Actually, all currently existing Python implementations always compile Python code, they never interpret it.
Why not just compile the whole thing?
That's a good question! Writing everything in the same language has many advantages, some of which I outlined above. (Another one is that it's easier to find collaborators who know one language than two.)
If everything is written in the same language, then performance improvements to that language get multiplied throughout the whole system. If everything is written in C, then making the Python 10 times faster isn't going to speed up your program much, because most of the code isn't Python. Sure, the code you wrote is running 10 times faster, but that code mostly consists of calls to C functions which have the same speed as before.
But if everything is written in Python, then making Python faster will have a ripple effect: the primitive types get faster, the datastructures built on top of those primitive types get faster, the algorithms using those datastructures get faster, the modules using those algorithms get faster and so on.
The interpreter itself is written in C (or at least the reference implementation CPython is). That means every language feature is implemented with a tiny C function. All the interpreter does is read the sourcecode to find out which of these tiny functions to call.
This means it is not a problem to also delegate more complex functions to C implementations.
These functions are not compiled with your program. They already exist in compiled form in the Python interpreter which just calls them when it encounters them in your sourcecode.
If the C variant needs x hours less, then I'd invest that time in letting the algorithms run longer/again
"invest" isn't the right word here.
Build a working implementation in Python. You'll finish this long before you'd finish a C version.
Measure performance with the Python profiler. Fix any problems you find. Change data structures and algorithms as necessary to really do this properly. You'll finish this long before you finish the first version in C.
If it's still too slow, manually translate the well-designed and carefully constructed Python into C.
Because of the way hindsight works, doing the second version from existing Python (with existing unit tests, and with existing profiling data) will still be faster than trying to do the C code from scratch.
This quote is important.
Thompson's Rule for First-Time Telescope Makers
It is faster to make a four-inch mirror and then a six-inch mirror than to make a six-inch mirror.Bill McKeenan
Wang Institute
Yes. Look at Cython. It does just that: Converts Python to C for speedups.
First off, interpreted/compiled is not a property of the language but a property of the implementation. For most languages, most if not all implementations fall in one category, so one might save a few words saying the language is interpreted/compiled too, but it's still an important distinction, both because it aids understanding and because there are quite a few languages with usable implementations of both kinds (mostly in the realm of functional languages, see Haskell and ML). In addition, there are C interpreters and projects that attempt to compile a subset of Python to C or C++ code (and subsequently to machine code).
Second, compilation is not restricted to ahead-of-time compilation to native machine code. A compiler is, more generally, a program that converts a program in one programming language into a program in another programming language (arguably, you can even have a compiler with the same input and output language if significant transformations are applied). And JIT compilers compile to native machine code at runtime, which can give speed very close to or even better than ahead of time compilation (depending on the benchmark and the quality of the implementations compared).
But to stop nitpicking and answer the question you meant to ask: Practically (read: using a somewhat popular and mature implementation), Python is compiled. Not compiled to machine code ahead of time (i.e. "compiled" by the restricted and wrong, but alas common definition), "only" compiled to bytecode, but it's still compilation with at least some of the benefits. For example, the statement a = b.c() is compiled to a byte stream which, when "disassembled", looks somewhat like load 0 (b); load_str 'c'; get_attr; call_function 0; store 1 (a). This is a simplification, it's actually less readable and a bit more low-level - you can experiment with the standard library dis module and see what the real deal looks like. Interpreting this is faster than interpreting from a higher-level representation.
That bytecode is either interpreted (note that there's a difference, both in theory and in practical performance, between interpreting directly and first compiling to some intermediate representation and interpret that), as with the reference implementation (CPython), or both interpreted and compiled to optimized machine code at runtime, as with PyPy.
The CPU can only understand machine code indeed. For interpreted programs, the ultimate goal of an interpreter is to "interpret" the program code into machine code. However, usually a modern interpreted language does not interpret human code directly because it is too inefficient.
The Python interpreter first reads the human code and optimizes it to some intermediate code before interpreting it into machine code. That's why you always need another program to run a Python script, unlike in C++ where you can run the compiled executable of your code directly. For example, c:\Python27\python.exe or /usr/bin/python.
Are there any libraries that can easily convert Python to C/C#/or C++? Ones where a person doesn't have to "calibrate" it, just, pip install library and then they can have their Python code in C,C#,or C++?
For all practical purposes, bytecode is just a data structure that is convenient for an interpreter to use. The interpreter looks at each instruction in the byte code and immediately performs that action.
A simple interpreter for arithmetic expressions might look like this when written in Python:
bytecode = [
{'type': 'const', 'value': 40},
{'type': 'const', 'value': 2},
{'type': '+'},
{'type': 'print'},
]
stack = []
for instruction in bytecode:
action = instruction['type']
if action == 'const':
stack.append(instruction['value'])
elif action == '+':
right = stack.pop()
left = stack.pop()
stack.append(left + right)
elif action == 'print':
print(stack.pop())
else:
raise TypeError(f'Unknown instruction type {action}')
That is, the interpreter checks the type of the type of the instruction and selects which code snippet to run depending on that action. The interpreter is not translating the bytecode into another language in the sense that we'd get a program in that language, but it does map the instructions to code snippets.
Thus, the CPython interpreter does not translate Python bytecode into C code, but selects which C code snippet to run depending on the instruction.
This is useful, because generating C code that works correctly and is as fast as expected from C is quite tricky. Interpreters typically spend a lot of time doing extra bookkeeping (like reference counting), and in the dispatch logic itself – that loop through all instructions isn't quite free.
Programs that translate a source language into another language are sometimes called a transpiler (a kind of compiler that doesn't output machine code). It is easy to create a transpiler that just calls into the code snippets of an interpreter (sometimes called threaded code in older literature):
bytecode = [
{'type': 'const', 'value': 40},
{'type': 'const', 'value': 2},
{'type': '+'},
{'type': 'print'},
]
# built-in function for our "compiled" code to call
def do_const(stack, value):
stack.append(value)
def do_add(stack):
right = stack.pop()
left = stack.pop()
stack.append(left + right)
def do_print(stack):
print(stack.pop())
# assembling Python source code for our "bytecode"
code = 'stack = []\n'
for instruction in bytecode:
action = instruction['type']
if action == 'const':
code += f'do_const(stack, {instruction["value"]})\n'
elif action == '+':
code += 'do_add(stack)\n'
elif action == 'print':
code += 'do_print(stack)\n'
else:
raise TypeError(f'Unknown instruction type {action}')
# we can now execute the code by "compiling" it as Python:
exec(code, locals(), {})
The resulting code might be slightly faster because we've gotten rid of the dispatch logic, but we still have interpreter overhead like stack manipulation. The code we've generated doesn't look like normal Python code. But to get to that Python code we still had to run through our dispatch logic, and now Python has to parse the code we've generated. Similarly, a Python interpreter that translates to C wouldn't be very fast.
The Java reference implementation OpenJDK/HotSpot is interesting because its runtime combines a just-in-time compiler with an interpreter. By default, it interprets byte code with an interpreter written in C++. But if the same code is executed often enough, it compiles that part of the code directly to machine code. Depending on how important that code is, HotSpot spends more effort on optimizing the machine code. This allows Java to be as fast as C in some benchmarks. CPython is very simplistic in comparison.
There is (was?) a Python implementation called Jython that was written in Java. Jython works by compiling the Python code to Java byte code. That byte code is then handled by the Java virtual machine, which either interprets it or compiles it on the fly to machine code, as discussed above. Because the Java runtime is awesome this could make that Python code run very fast, in some circumstances. But the added complexity also comes at a cost. Additionally, Jython is not compatible with Python modules that need to interact with internal CPython data structures.
what i know is , in cpython when we run a code then its first compiled into byte code and the cpython interpreter( which is written in c interprets it) interprets the byte code and converts it into machine code.
No, it doesn't "convert it into machine code." That would be a compiler, not an interpreter.
A compiler is a program which takes a program written in Language A and converts it into a semantically equivalent program written in Language B.
An interpreter is a program which takes a program written in Language A and runs it.
Does that mean the byte code is represented as c code by the interpreter and then its carried out as c code ?
It's not clear what you mean by that. CPython is written in C, so in some sense, at some point, the byte code will be represented by some sort of C data structure, even if just as a byte[]. So, in some sense, there is some sort of representation in C.
what exactly does it mean when we say python interpreter is written in c/java? how do they differ in their process of converting byte code into machine code?
They don't convert byte code into machine code.
Again, an interpreter doesn't convert. It interprets.
A compiler converts.
Maybe you are confused by the standard English meaning of interpreter which is a person that translates from language to another language in real time. That is not what is meant when we use the term interpreter in programming.
Words can have different meanings in different contexts, the same word can mean different things in "general" English and in Programming Jargon.
what exactly does the interpreter do with the Byte code?
The simplest answer is: it runs it.
For example, if you have an ADD byte code whose semantics are that you take the two values on top of the stack, add them, and put the result back on the stack, the byte code interpreter will then do exactly that: it will take two values from the stack, add them, and put the result back on the stack. (Assuming we are using a stack-based VM, which I believe CPython does.)
I wrote a little bit about the differences between interpreters and compilers in my answer to the question Understanding the differences: traditional interpreter, JIT compiler, JIT interpreter and AOT compiler, in case you are interested.