interpreter vs. compiled

castironpi castironpi at gmail.com
Fri Jul 18 20:17:56 CEST 2008


On Jul 17, 11:39 pm, Kay Schluehr <kay.schlu... at gmx.net> wrote:
> On 18 Jul., 01:15, castironpi <castiro... at gmail.com> wrote:
>
>
>
> > On Jul 17, 5:37 pm, I V <ivle... at gmail.com> wrote:
>
> > > On Thu, 17 Jul 2008 15:08:17 -0700, castironpi wrote:
> > > > The Python disassembly is baffling though.
>
> > > >>>> y= 3
> > > >>>> dis.dis('x=y+1')
>
> > > You can't disassemble strings of python source (well, you can, but, as
> > > you've seen, the results are not meaningful). You need to compile the
> > > source first:
>
> > > >>> code = compile('y=x+1','-', 'single')
> > > >>> dis.dis(code)
>
> > >   1           0 LOAD_NAME                0 (x)
> > >               3 LOAD_CONST               0 (1)
> > >               6 BINARY_ADD
> > >               7 STORE_NAME               1 (y)
> > >              10 LOAD_CONST               1 (None)
> > >              13 RETURN_VALUE
>
> > > You may well find these byte codes more meaningful. Note that there is a
> > > list of opcodes athttp://docs.python.org/lib/bytecodes.html
>
> > Oh.  How is the stack represented?
>
> As a pointer to a pointer of PyObject structs.
>
> > Does it keep track of which stack
> > positions (TOS, TOS1, etc.) are in what registers?  Does stack
> > manipulation consume processor cycles?
>
> Python does not store values in registers. It stores locals in arrays
> and accesses them by position ( you can see the positional index in
> the disassembly right after the opcode name ) and globals / object
> attributes in dicts.
>
> For more information you might just download the source distribution
> and look for src/Python/ceval.c. This file contains the main
> interpreter loop.

Ah, found it.  The parts that are making sense are:

register PyObject **stack_pointer;
#define TOP()		(stack_pointer[-1])
#define BASIC_POP()	(*--stack_pointer)

...(line 1159)...
w = POP();
v = TOP();
if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
	/* INLINE: int + int */
	register long a, b, i;
	a = PyInt_AS_LONG(v);
	b = PyInt_AS_LONG(w);
	i = a + b;
	if ((i^a) < 0 && (i^b) < 0)
		goto slow_add;
	x = PyInt_FromLong(i);

... Which is more than I was picturing was involved.  I understand it
is also specific to CPython.  Thanks for the pointer to the code.

My basic question was, what is the difference between compilers and
interpreters, and why are interpreters slow?  I'm looking at some of
the answer right now in "case BINARY_ADD:".



More information about the Python-list mailing list