Le jeudi 19 mai 2011 à 10:47 +1200, Greg Ewing a écrit :
Victor Stinner wrote:
squares = (x*x for x in range(10000))
What bytecode would you optimise that into?
I suppose that you have the current value of range(10000) on the stack: DUP_TOP; BINARY_MULTIPLY; gives you the square. You don't need the x variable (LOAD_FAST/STORE_FAST). Full example using a function (instead of loop, so I need to load x): ----------- import dis, opcode, struct def f(x): return x*x def patch_bytecode(f, bytecode): fcode = f.__code__ code_type = type(f.__code__) new_code = code_type( fcode.co_argcount, fcode.co_kwonlyargcount, fcode.co_nlocals, fcode.co_stacksize, fcode.co_flags, bytecode, fcode.co_consts, fcode.co_names, fcode.co_varnames, fcode.co_filename, fcode.co_name, fcode.co_firstlineno, fcode.co_lnotab, ) f.__code__ = new_code print("Original:") print("f(4) = %s" % f(4)) dis.dis(f) print() LOAD_FAST = opcode.opmap['LOAD_FAST'] DUP_TOP = opcode.opmap['DUP_TOP'] BINARY_MULTIPLY = opcode.opmap['BINARY_MULTIPLY'] RETURN_VALUE = opcode.opmap['RETURN_VALUE'] bytecode = struct.pack( '=BHBBB', LOAD_FAST, 0, DUP_TOP, BINARY_MULTIPLY, RETURN_VALUE) print("Patched:") patch_bytecode(f, bytecode) print("f(4) patched = %s" % f(4)) dis.dis(f) ----------- Output: ----------- $ python3 square.py Original: f(4) = 16 3 0 LOAD_FAST 0 (x) 3 LOAD_FAST 0 (x) 6 BINARY_MULTIPLY 7 RETURN_VALUE Patched: f(4) patched = 16 3 0 LOAD_FAST 0 (x) 3 DUP_TOP 4 BINARY_MULTIPLY 5 RETURN_VALUE ----------- Victor