fastest way to detect a user type

Robin Becker robin at NOSPAMreportlab.com
Sat Jan 31 11:39:23 EST 2009


Whilst considering a port of old code to python 3 I see that in several 
places we are using type comparisons to control processing of user 
instances (as opposed to instances of built in types eg float, int, str)

I find that the obvious alternatives are not as fast as the current 
code; func0 below. On my machine isinstance seems slower than type for 
some reason. My 2.6 timings are

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func0(v)
1000000 loops, best of 3: 0.348 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func1(v)
1000000 loops, best of 3: 0.747 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func2(v)
1000000 loops, best of 3: 0.378 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func3(v)
1000000 loops, best of 3: 0.33 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func0(1)
1000000 loops, best of 3: 0.477 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func1(1)
1000000 loops, best of 3: 1.14 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func2(1)
1000000 loops, best of 3: 1.16 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"import t;v=t.X()" t.func3(1)
1000000 loops, best of 3: 1.14 usec per loop

so func 3 seems to be the fastest option for the case when the first 
test matches, but is poor when it doesn't. Can anyone suggest a better 
way to determine if an object is a user instance?

##############################
from types import InstanceType
class X:
     __X__=True

class V(X):
     pass

def func0(ob):
     t=type(ob)
     if t is InstanceType:
         pass
     elif t in (float, int):
         pass
     else:
         pass

def func1(ob):
     if isinstance(ob,X):
         pass
     elif type(ob) in (float, int):
         pass
     else:
         pass

def func2(ob):
     if getattr(ob,'__X__',False):
         pass
     elif type(ob) in (float, int):
         pass
     else:
         pass

def func3(ob):
     if hasattr(ob,'__X__'):
         pass
     elif type(ob) in (float, int):
         pass
     else:
         pass
##############################

-- 
Robin Becker



More information about the Python-list mailing list