[Types-sig] Low-hanging fruit: recognizing builtins

M.-A. Lemburg mal@lemburg.com
Thu, 16 Dec 1999 11:02:49 +0100


Guido van Rossum wrote:
> 
> > How about also adding caching of globals
> > which are not modified within the module in locals ? This
> > would save another cylce or two. The caching would have
> > to take place during function creation time. I'm currently doing
> > this by hand which results in ugly code... :-( but faster execution
> > :-)
> 
> Indeed -- the same analysis I was proposing would also support this.
> However there's a common pattern that can be a problem here (and isn't
> a problem for the built-in functions analysis): modules often have a
> few global variables that are initialized only once in the module, but
> are clearly (e.g. through comments) intended to be modified by using
> modules.  Examples: default files, debug levels, and the like.  I'm
> not sure how to detect this pattern reliably, unless you decide to
> cache only functions, classes, and imported modules.

In the long run it would be better to wrap those module
globals with write access functions (the write action would
then be recognized by the optimizer).

I haven't followed the thread too closely, but isn't there
some way to tell the optimizer which modules to treat at
what optimization level ? Old modules should only use the
"safe" caching strategy then while modules compiled with
full optimization would be caching all read-only globals.

BTW, instead of adding oodles of new byte code, how about
grouping them... e.g. instead of UNARY_LEN, BUILD_RANGE, etc.
why not have a CALL_BUILTIN which takes an index into
a predefined set of builtin functions.

The same could be done with some often used constants
such as None, '', 1, 0: LOAD_SYSTEM_CONST with an index
into a constants array.

The advantage is that you can easily extend both sets
of prefetched constants while not adding too many
new new byte codes to the inner loop.

Note that the loop as it is built now is already too large
for common Intel+compatible based CPUs. Adding even more byte
codes to the huge single loop would probably result in a
decrease of CPU cache hits. (I split the Great Switch
in two switch statements and got some good results out of
this: the first switch handles often used byte codes while the
second takes care of the more exotic ones.)

A note on range() and for: the common usage of

for i in range(const):
   ...

could be compiled into a completely different set of opcodes
not creating any list or tuple at all. Since the FOR_LOOP
opcode generates loop integers on each iteration the creation
of a range tuple or list is not needed. The loop opcode would only
have to check for the upper bound "const". I've added a new
counter type (basically a mutable integer type that allows
for fast increment and decrement) to simplify this even more.
For the curious, it's in the old patch:

    http://starship.skyport.net/~lemburg/mxPython-1.5.patch.gz

> > Note that interning the builtins as byte codes could be
> > a security risk when executing in a restricted environment,
> > though. Some builtin operations might not be allowed and but would
> > still be available via bytecode.
> 
> Of course a restricted environment should not accept arbitrary
> bytecode!  Also you could simply not define bytecodes for
> security-sensitive built-ins; the only ones I cna think of right now
> are __import__() and open(), which I already mentioned as exceptions.
> 
> Note that a bunch of built-in constants can also be optimized using
> this same mechanism: None and perhaps exception names.  I'm not sure
> that exception names are worth it though; they don't tend to be
> touched in inner loops where performance gains are made.  But None is
> definitely worth its own 1-byte opcode.

See above: I'd rather like see the addition of more generic
opcodes than many different new ones for each common
constant.

-- 
Marc-Andre Lemburg
______________________________________________________________________
Y2000:                                                    15 days left
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/