Weird try-except vs if behavior

Ryan Kelly ryan at rfk.id.au
Fri Oct 15 03:11:12 EDT 2010


On Thu, 2010-10-14 at 22:43 -0700, James Matthews wrote:
> Hi,
> 
> I have this code http://gist.github.com/627687 (I don't like pasting
> code into the mailing list).

Yes, but it makes it harder to discuss the ode and makes the archive
that much more useless.  It's only a couple of lines, here ya go:

  def tryway():
      try:
          while True:
              alist.pop()
      except IndexError:
          pass


  def ifway():
      while True:
          if blist == []: 
              break
          else:
              blist.pop()
            
  if __name__=='__main__':
      alist = range(1000)
      blist = range(1000)
      from timeit import Timer
      print "Testing Try"
      tr = Timer("tryway()","from __main__ import tryway")
      print tr.timeit()
      print "Testing If"
      ir = Timer("ifway()","from __main__ import ifway")
      print ir.timeit()


>  I am wondering why the try except is taking longer. I assume that if
> the IF statement checks every iteration of the loop (1000 times)
> shouldn't it be slower?

You're not measuring what you think.  The way you've structured your
code, "alist" and "blist" are module globals.

Timeit will call the "tryway" function one million times in a loop.  The
first time it works as you expect, popping each element off of "alist"
in turn.  On the other 999999 executions, "alist" is already empty
(having been emptied by the first execution) and the IndexError is
raised immediately.

Likewise for the execution of "ifway".

So what you're really measuring is the overhead of catching an exception
versus testing a condition for an *empty* list - no surprise that the
conditional version is faster!

If you re-initialise the list at the beginning of each function, the
try-based version is faster as you expect.  I.e.:

  def tryway(): 
      alist = range(1000) 
      try:
          while True:
              alist.pop()
      except IndexError:
          pass

I get the following times for a thousand iterations (not waiting around
for a million!)

  Testing Try
  0.224129915237
  Testing If
  0.300312995911


  Cheers,

     Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
ryan at rfk.id.au        |  http://www.rfk.id.au/ramblings/gpg/ for details

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/python-list/attachments/20101015/abfc6410/attachment.sig>


More information about the Python-list mailing list