Two questions about efficiency

From: Steve M (humean_at_fea.st)
Date: 05/26/04


Date: 26 May 2004 13:39:30 -0700

1. Near the beginning of the document "Unifying types and classes in
Python 2.2" by GvR, which can be found at
http://www.python.org/2.2.2/descrintro.html, the author writes the
following about subclassing a built in type:

---
Here's an example of a simple dict subclass, which provides a "default
value" that is returned when a missing key is requested:
    class defaultdict(dict):
        def __init__(self, default=None):
            dict.__init__(self)
            self.default = default
        def __getitem__(self, key):
            try:
                return dict.__getitem__(self, key)
            except KeyError:
                return self.default
<snip>
The __getitem__() method could also be written as follows, using the
new "key in dict" test introduced in Python 2.2:
        def __getitem__(self, key):
            if key in self:
                return dict.__getitem__(self, key)
            else:
                return self.default
I believe that this version is less efficient, because it does the key
lookup twice. The exception would be when we expect that the requested
key is almost never in the dictionary: then setting up the try/except
statement is more expensive than the failing "key in self" test.
---
I am interested in his claim that the second version is less efficient
unless the requested key is "almost never" in the dictionary. I would
have thought that the overhead to do a key lookup is quite a bit less
than the overhead required to create an exception object, so that the
first version would be on average more efficient only if the requested
key is in the dictionary, say, more than half the time.
Does the "key in dict" test internally raise an exception on failure,
thus incurring at least the same overhead as the first version? Or is
the overhead to raise an exception much less than I have naively
supposed?
I have a similar idiom buried in a nested loop, and I'd like to select
the approach that is likely to be most efficient. My best guess is
that the key lookup will fail half the time.
2. Is there any reason to prefer one of the following over the other?
Im interested in both a consensus on style and readability, and
considerations of efficiency at runtime.
for x in L:
  if f(x):
    pass
for x in L:
  if f(x):
    continue


Relevant Pages

  • Re: decorators tutorials
    ... I am learning python by learning django, ... allow the SystemExit exception to continue to propogate without doing ... # The func argument is a Pythong function object ... trying to get the result of DivXY, ...
    (comp.lang.python)
  • Re: math.nroot [was Re: A brief question.]
    ... >>> wish sometimes that Python would make up it's mind about what it does ... >> exception on overflow, invalid operation, and divide by 0, and "should ... >> not", by default, raise an exception on underflow or inexact. ... you can at least be pretty sure that an infinite result is the ...
    (comp.lang.python)
  • Re: exceptions
    ... How do younger languages like IO make this point more forcefully than lisp, ... deal with *all* errors in an interactive session, ... certainly in python ... > exception handling is hard-coded in syntax. ...
    (comp.lang.python)
  • Re: Learning to use decorators with classes
    ... and you could use any legal Python identified instead. ... This kind of "error handling" is more than useless - it's worse than no error handling at all. ... If you cannot handle the problem, just let the exception propagate - you'll get a nice traceback with all the necessary debugging informations. ... Users of your package can always add a top-level "catch-all" exception handler that will log tracebacks, send alert mails to the team, and present the end-user with a nicely formatted error message (and even possibly a way to handle the problem - like providing appropriate connection data (credentials, url, whatever)!-) ...
    (comp.lang.python)
  • Re: JSON Strict Mode
    ... Here's one that uses Python and that I've heard praise for: ... How would i go about checking if its in "strict mode" ... an exception is type of object** used to indicate that ... error into a new exception object and then "raises" (using, in Python, ...
    (comp.lang.python)