On Wed, Feb 26, 2003 at 01:06:44PM -0500, Terry Reedy wrote: > > "Skip Montanaro" <skip@pobox.com> wrote in message > news:15964.59840.342254.176499@montanaro.dyndns.org... > > For code that wants to cleanly cross the boundary between Python > with no > > boolean type and Python with a boolean type, you sometimes see > > > > True = 1==1 > > False = 1==0 > > > > You get True and False if it didn't exist before and have the added > benefit > > that if it does exist, it gets found in globals() or locals() > instead of in > > __builtins__ and has the right type. > > This suggests a more radical optimization that might do more speedup > than all the byte-code fiddling currently proposed: automatically > localize, at definition time, builtins used within a function. This > would be like giving each function a customized implicit set of > default args: True=True, None=None, len=len, ...etc. > If a program alters __builtins__, def statement placement would > determine which version gets used. > Hi, I have a piece of code that does (almost) exactly that, except at runtime. It's purpose is to optimize access to globals used as constants by replacing the LOAD_GLOBAL opcode by a LOAD_CONST. It does that by creating a new code object for the function you provide and using a list of symbols to consider constant. I called it bind, because it works like the postscript bind operator the code for the main function is below, you can find the full module at ftp://ftp.logilab.org/pub/tmp/bind.py it can provide a 10% speedup although most of the time it is around 3% to 5% regards, Ludovic from dis import HAVE_ARGUMENT from new import code as make_code, function as make_function import inspect LOAD_GLOBAL = 116 LOAD_CONST = 100 EXTENDED_ARG = 143 STORE_GLOBAL = 97 def bind_code(co,globals): """Take a code object and a dictionnary and returns a new code object where the opcodes LOAD_GLOBAL are replaced by LOAD_CONST whenever the global's name appear in the dictionnary""" consts = list(co.co_consts) assigned = {} code = co.co_code new_code="" n = len(code) i = 0 while i < n: c = code[i] op = ord(c) i+=1 if op >= HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 i += 2 else: oparg=None if op == LOAD_GLOBAL: name = co.co_names[oparg] if globals.has_key(name): k = assigned.get(name,None) if k==None: k=len(consts) assigned[name]=len(consts) consts.append(globals[name]) op = LOAD_CONST oparg=k new_code+=chr(op) if oparg is not None: new_code += chr(oparg & 255) new_code += chr( (oparg>>8) & 255 ) return make_code(co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, new_code, tuple(consts), co.co_names, co.co_varnames, co.co_filename, co.co_name, co.co_firstlineno, co.co_lnotab ) def bind(f,globals): """Returns a new function whose code object has been bound by bind_code()""" newcode = bind_code(f.func_code,globals) defaults = f.func_defaults or () return make_function(newcode,f.func_globals,f.func_name,defaults) -- Ludovic Aubry LOGILAB, Paris (France). http://www.logilab.com http://www.logilab.fr http://www.logilab.org
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4