[New-bugs-announce] [issue2179] with should be as fast as try/finally

Jeffrey Yasskin report at bugs.python.org
Mon Feb 25 00:10:41 CET 2008


New submission from Jeffrey Yasskin:

Currently, 'with' costs about .2us over try/finally:

$ ./python.exe -m timeit -s 'import thread; lock =
thread.allocate_lock()' 'lock.acquire()' 'try: pass' 'finally:
lock.release()'
1000000 loops, best of 3: 0.617 usec per loop
$ ./python.exe -m timeit -s 'import thread; lock =
thread.allocate_lock()' 'with lock: pass'
1000000 loops, best of 3: 0.774 usec per loop

Since it's doing the same thing (and calling the same C functions to do
the lock manipulation), it shouldn't take more time. The bytecodes
associated with the two options look like:

2)    with lock:
3)      pass

 2           0 LOAD_GLOBAL              0 (lock)
              3 DUP_TOP             
              4 LOAD_ATTR                1 (__exit__)
              7 STORE_FAST               0 (_[1])
             10 LOAD_ATTR                2 (__enter__)
             13 CALL_FUNCTION            0
             16 POP_TOP             
             17 SETUP_FINALLY            4 (to 24)

  3          20 POP_BLOCK           
             21 LOAD_CONST               0 (None)
        >>   24 LOAD_FAST                0 (_[1])
             27 DELETE_FAST              0 (_[1])
             30 WITH_CLEANUP        
             31 END_FINALLY         
             32 LOAD_CONST               0 (None)
             35 RETURN_VALUE        


6)    lock.acquire()
7)    try:
8)      pass
9)    finally:
10)     lock.release()

  6           0 LOAD_GLOBAL              0 (lock)
              3 LOAD_ATTR                1 (acquire)
              6 CALL_FUNCTION            0
              9 POP_TOP             

  7          10 SETUP_FINALLY            4 (to 17)

  8          13 POP_BLOCK           
             14 LOAD_CONST               0 (None)

 10     >>   17 LOAD_GLOBAL              0 (lock)
             20 LOAD_ATTR                2 (release)
             23 CALL_FUNCTION            0
             26 POP_TOP             
             27 END_FINALLY         
             28 LOAD_CONST               0 (None)
             31 RETURN_VALUE


The major difference I see is the extra local variable (_[1]) used by
with. It looks like the compiler ought to be able to save that on the
stack instead, and save 3 opcodes. Neal Norwitz suggested that, if that
optimization is impossible, WITH_CLEANUP could be modified to take the
variable as a parameter, which would let it absorb the LOAD_FAST and
DELETE_FAST instructions.

I've added everyone on the previous bug to the nosy list. Sorry if you
don't care. :)

----------
components: Interpreter Core
messages: 62951
nosy: amaury.forgeotdarc, benjamin.peterson, jyasskin, nnorwitz, rhettinger, tiran
severity: normal
status: open
title: with should be as fast as try/finally
type: feature request
versions: Python 2.6

__________________________________
Tracker <report at bugs.python.org>
<http://bugs.python.org/issue2179>
__________________________________


More information about the New-bugs-announce mailing list