[Zope3-dev] interface conventions: default=_RAISE_ERROR

Tres Seaver tseaver@zope.com
15 May 2002 11:12:01 -0400


On Wed, 2002-05-15 at 10:10, Barry A. Warsaw wrote:

> Years ago (circa 1.5.2?) I did some tests with KeyError, has_key(),
> and __getitem__() and found that the balance point was at about a hit
> rate of 92%.  Meaning, if 92% of your accesses succeed, it was faster
> to catch the exception than to do a has_key() test first, because the
> exception happened rarely enough.  If fewer than 92% of your accesses
> succeeded then it was faster to do a has_key() test first because of
> the overhead of the exception machinery.  This led us to adding get()
> with a failobj argument so that you could almost always avoid the
> exception and you'd get better performance.
> 
> I'm sure the exact numbers have changed since then, but I think the
> general rule-of-thumb still applies.  The trade-off depends on whether
> you think most of your accesses will fail or succeed.

I think the cost exceptions got *markedly* higher in Python 2, which
makes the threshold much closer to unity.  I prefer to use exceptions
for the things they are good at, which is primarily to avoid the kruft
of propagating the exceptional result out to the level where somebody
has enough context to handle them.  For the simple case, where the
caller will always handle the exception, I prefer to use a distinguished
return value.

> Raising and catching the exception in Python will always be slower
> than returning the default.  Think about it: you have to instantiate
> the exception class, then you have to do isinstance() tests of all the
> base classes until you find a match.
> 
>     FG> (And prefer to see "default" spelt "error_value" or "missing"
>     FG> to better show the intent.)
> 
> I use `failobj' but `missing' would be fine with me.

Tres.
-- 
===============================================================
Tres Seaver                                tseaver@zope.com
Zope Corporation      "Zope Dealers"       http://www.zope.com