This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author jyasskin
Recipients amaury.forgeotdarc, benjamin.peterson, christian.heimes, jyasskin, nnorwitz, rhettinger
Date 2008-02-24.23:10:39
SpamBayes Score 0.010346757
Marked as misclassified No
Message-id <1203894641.18.0.492382147443.issue2179@psf.upfronthosting.co.za>
In-reply-to
Content
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. :)
History
Date User Action Args
2008-02-24 23:10:41jyasskinsetspambayes_score: 0.0103468 -> 0.010346757
recipients: + jyasskin, nnorwitz, rhettinger, amaury.forgeotdarc, christian.heimes, benjamin.peterson
2008-02-24 23:10:41jyasskinsetspambayes_score: 0.0103468 -> 0.0103468
messageid: <1203894641.18.0.492382147443.issue2179@psf.upfronthosting.co.za>
2008-02-24 23:10:40jyasskinlinkissue2179 messages
2008-02-24 23:10:39jyasskincreate