# __COPYRIGHT__ # # Benchmarks for testing various possible implementations # of the is_Dict(), is_List() and is_String() functions in # SCons/Util.py. import types from collections import UserDict, UserList, UserString, deque from collections.abc import Iterable, MappingView, MutableMapping, MutableSequence DictType = dict ListType = list StringType = str # The original implementations, pretty straightforward checks for the # type of the object and whether it's an instance of the corresponding # User* type. def original_is_Dict(e): return isinstance(e, (dict, UserDict)) def original_is_List(e): return isinstance(e, (list, UserList)) def original_is_String(e): return isinstance(e, (str, UserString)) # New candidates that explicitly check for whether the object is an # InstanceType before calling isinstance() on the corresponding User* # type. Update: meaningless in Python 3, InstanceType was only for # old-style classes, so these are just removed. # XXX # New candidates that try more generic names from collections: def new_is_Dict(e): return isinstance(e, MutableMapping) def new_is_List(e): return isinstance(e, MutableSequence) def new_is_String(e): return isinstance(e, (str, UserString)) # Improved candidates that cache the type(e) result in a variable # before doing any checks. def cache_type_e_is_Dict(e): t = type(e) return t is dict or isinstance(e, UserDict) def cache_type_e_is_List(e): t = type(e) return t is list or isinstance(e, (UserList, deque)) def cache_type_e_is_String(e): t = type(e) return t is str or isinstance(e, UserString) # Improved candidates that cache the type(e) result in a variable # before doing any checks, but using the global names for # DictType, ListType and StringType. def global_cache_type_e_is_Dict(e): t = type(e) return t is DictType or isinstance(e, UserDict) def global_cache_type_e_is_List(e): t = type(e) return t is ListType or isinstance(e, (UserList, deque)) def global_cache_type_e_is_String(e): t = type(e) return t is StringType or isinstance(e, UserString) # Alternative that uses a myType() function to map the User* objects # to their corresponding underlying types. # Again, since this used InstanceType, it's not useful for Python 3. # These are the actual test entry points def Func01(obj): """original_is_String""" for i in IterationList: original_is_String(obj) def Func02(obj): """original_is_List""" for i in IterationList: original_is_List(obj) def Func03(obj): """original_is_Dict""" for i in IterationList: original_is_Dict(obj) def Func04(obj): """new_is_String""" for i in IterationList: new_is_String(obj) def Func05(obj): """new_is_List""" for i in IterationList: new_is_List(obj) def Func06(obj): """new_is_Dict""" for i in IterationList: new_is_Dict(obj) def Func07(obj): """cache_type_e_is_String""" for i in IterationList: cache_type_e_is_String(obj) def Func08(obj): """cache_type_e_is_List""" for i in IterationList: cache_type_e_is_List(obj) def Func09(obj): """cache_type_e_is_Dict""" for i in IterationList: cache_type_e_is_Dict(obj) def Func10(obj): """global_cache_type_e_is_String""" for i in IterationList: global_cache_type_e_is_String(obj) def Func11(obj): """global_cache_type_e_is_List""" for i in IterationList: global_cache_type_e_is_List(obj) def Func12(obj): """global_cache_type_e_is_Dict""" for i in IterationList: global_cache_type_e_is_Dict(obj) # Data to pass to the functions on each run. Each entry is a # three-element tuple: # # ( # "Label to print describing this data run", # ('positional', 'arguments'), # {'keyword' : 'arguments'}, # ), class A: pass Data = [ ( "String", ('',), {}, ), ( "List", ([],), {}, ), ( "Dict", ({},), {}, ), ( "UserString", (UserString(''),), {}, ), ( "UserList", (UserList([]),), {}, ), ( "deque", (deque([]),), {}, ), ( "UserDict", (UserDict({}),), {}, ), ( "Object", (A(),), {}, ), ] # Local Variables: # tab-width:4 # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: