On Tue, 10 Nov 2015 05:10 pm, Ben Finney wrote: > Steven D'Aprano <st...@pearwood.info> writes: > >> Ben, I fear that you are not paying attention to me :-) > > Possibly, though I also think there's miscommunication in this thread. > > You speak of “compile time” and “run time”. You also speak of what the > compiler can do, at run time. > > I am a Bear of Little Brain, but: Isn't anything that the *compiler* > does, by definition done at *compile* time?
In a manner of speaking, yes, of course. But you've missed the critical issue: when is compile time? If you're like most people, you probably are thinking about an execution model where the compiler analyses the source code statically, using nothing but what can be seen in the source code, then hands over some sort of compiled byte code to be run by an interpreter or machine code that is executed by the CPU. The compiler and interpreter are completely distinct. If so, you're stuck with an obsolete model of computation, like somebody trying to understand modern chemistry based on the "planetary orbit" model of the atom. So when is compile time? Of course, in some languages (like C, or Pascal) compilation occurs as a distinct stage before you can run the code. But that's not necessarily true for all compilers. "Just In Time" compilers operate while the program is running, compiling code just before it is executed. The distinction between compiler and interpreter is gone, or at least weakened. Python -- yes, even CPython -- has a runtime compiler. When you import a module, it is compiled (if needed) just before the import. Likewise, when you call the `compile`, `eval` or `exec` built-ins, the compiler operates. I'm not calling this a JIT compiler, because the simple-minded compilation performed by `compile` etc doesn't use any run-time information. It just statically compiles the code to byte-code. But the fact that it happens *at runtime* is significant, because in principle there is a lot more information available to the compiler, if it were intelligent enough to make use of it. For example, suppose you execute this Python snippet: result = x + 2 At static compile time, looking just at the source, you may not know what value x is, or even whether or not x actually exists, so you're forced to go through the standard Python semantics to determine what the result is: py> from dis import dis py> dis("result = x + 1") 1 0 LOAD_NAME 0 (x) 3 LOAD_CONST 0 (1) 6 BINARY_ADD 7 STORE_NAME 1 (result) 10 LOAD_CONST 1 (None) 13 RETURN_VALUE But a JIT compiler gets to compile code right before that line is due to execute. By the time the JIT compiler gets to see that line of code, it can already know whether or not name "x" exists, and if so, which namespace it is in. It knows what value "x" has. The compiler can choose what byte code, or even machine code, to generate, using information available just before that code is needed. Suppose it knows that "x" is bound to an float. Then it can cast the int 1 to the machine floating point double 1.0 and generate code that adds that to a float. That's likely to be tens of times faster than the BINARY_ADD op-code, which has to do a whole lot of type-checking, method calling, and creating and disposing of objects to add the two values. Only if "x" is unknown, or if it is some type that doesn't have a convenient optimization, does the JIT compiler generate the standard (but unoptimized) BINARY_ADD op-code. Provided that, on average, the book-keeping needed by the JIT compiler is outweighed by the gains, the whole process counts as a win. Now, CPython doesn't include a JIT compiler. But PyPy does, and it is much more sophisticated than anything I could explain. I'm not the only one: https://glyph.twistedmatrix.com/2012/02/this-isnt-how-pypy-works-but-it-might.html If you remember Psycho, that might help. Psycho (according to its creator) isn't a "true" JIT compiler, but it's close enough. Psycho would generate machine code -- actual low level code running in the CPU or FPU, not byte code -- for certain Python operations, plus guard code that ensured the machine code was only called when it was safe to do so. So this is long proven technology. More about JIT compilation on Wikipedia: https://en.wikipedia.org/wiki/Just-in-time_compilation -- Steven -- https://mail.python.org/mailman/listinfo/python-list