f9f76770c271f840642be2550057c48b388589ca
[scons.git] / bench / is_types.py
1 # __COPYRIGHT__
2 #
3 # Benchmarks for testing various possible implementations
4 # of the is_Dict(), is_List() and is_String() functions in
5 # src/engine/SCons/Util.py.
6
7 import types
8 from UserDict import UserDict
9 from UserList import UserList
10
11 try:
12     from UserString import UserString
13 except ImportError:
14     # "Borrowed" from the Python 2.2 UserString module
15     # and modified slightly for use with SCons.
16     class UserString:
17         def __init__(self, seq):
18             if type(seq) == type(''):
19                 self.data = seq
20             elif isinstance(seq, UserString):
21                 self.data = seq.data[:]
22             else:
23                 self.data = str(seq)
24         def __str__(self): return str(self.data)
25         def __repr__(self): return repr(self.data)
26         def __int__(self): return int(self.data)
27         def __long__(self): return long(self.data)
28         def __float__(self): return float(self.data)
29         def __complex__(self): return complex(self.data)
30         def __hash__(self): return hash(self.data)
31
32         def __cmp__(self, s):
33             if isinstance(s, UserString):
34                 return cmp(self.data, s.data)
35             else:
36                 return cmp(self.data, s)
37         def __contains__(self, char):
38             return char in self.data
39
40         def __len__(self): return len(self.data)
41         def __getitem__(self, index): return self.__class__(self.data[index])
42         def __getslice__(self, start, end):
43             start = max(start, 0); end = max(end, 0)
44             return self.__class__(self.data[start:end])
45
46         def __add__(self, other):
47             if isinstance(other, UserString):
48                 return self.__class__(self.data + other.data)
49             elif is_String(other):
50                 return self.__class__(self.data + other)
51             else:
52                 return self.__class__(self.data + str(other))
53         def __radd__(self, other):
54             if is_String(other):
55                 return self.__class__(other + self.data)
56             else:
57                 return self.__class__(str(other) + self.data)
58         def __mul__(self, n):
59             return self.__class__(self.data*n)
60         __rmul__ = __mul__
61
62 InstanceType = types.InstanceType
63 DictType = types.DictType
64 ListType = types.ListType
65 StringType = types.StringType
66 if hasattr(types, 'UnicodeType'):
67     UnicodeType = types.UnicodeType
68
69
70 # The original implementations, pretty straightforward checks for the
71 # type of the object and whether it's an instance of the corresponding
72 # User* type.
73
74 def original_is_Dict(e):
75     return type(e) is types.DictType or isinstance(e, UserDict)
76
77 def original_is_List(e):
78     return type(e) is types.ListType or isinstance(e, UserList)
79
80 if hasattr(types, 'UnicodeType'):
81     def original_is_String(e):
82         return type(e) is types.StringType \
83             or type(e) is types.UnicodeType \
84             or isinstance(e, UserString)
85 else:
86     def original_is_String(e):
87         return type(e) is types.StringType or isinstance(e, UserString)
88
89
90
91 # New candidates that explicitly check for whether the object is an
92 # InstanceType before calling isinstance() on the corresponding User*
93 # type.
94
95 def checkInstanceType_is_Dict(e):
96     return type(e) is types.DictType or \
97            (type(e) is types.InstanceType and isinstance(e, UserDict))
98
99 def checkInstanceType_is_List(e):
100     return type(e) is types.ListType \
101         or (type(e) is types.InstanceType and isinstance(e, UserList))
102
103 if hasattr(types, 'UnicodeType'):
104     def checkInstanceType_is_String(e):
105         return type(e) is types.StringType \
106             or type(e) is types.UnicodeType \
107             or (type(e) is types.InstanceType and isinstance(e, UserString))
108 else:
109     def checkInstanceType_is_String(e):
110         return type(e) is types.StringType \
111             or (type(e) is types.InstanceType and isinstance(e, UserString))
112
113
114
115 # Improved candidates that cache the type(e) result in a variable
116 # before doing any checks.
117
118 def cache_type_e_is_Dict(e):
119     t = type(e)
120     return t is types.DictType or \
121            (t is types.InstanceType and isinstance(e, UserDict))
122
123 def cache_type_e_is_List(e):
124     t = type(e)
125     return t is types.ListType \
126         or (t is types.InstanceType and isinstance(e, UserList))
127
128 if hasattr(types, 'UnicodeType'):
129     def cache_type_e_is_String(e):
130         t = type(e)
131         return t is types.StringType \
132             or t is types.UnicodeType \
133             or (t is types.InstanceType and isinstance(e, UserString))
134 else:
135     def cache_type_e_is_String(e):
136         t = type(e)
137         return t is types.StringType \
138             or (t is types.InstanceType and isinstance(e, UserString))
139
140
141
142 # Improved candidates that cache the type(e) result in a variable
143 # before doing any checks, but using the global names for
144 # DictType, ListType and StringType.
145
146 def global_cache_type_e_is_Dict(e):
147     t = type(e)
148     return t is DictType or \
149            (t is InstanceType and isinstance(e, UserDict))
150
151 def global_cache_type_e_is_List(e):
152     t = type(e)
153     return t is ListType \
154         or (t is InstanceType and isinstance(e, UserList))
155
156 if hasattr(types, 'UnicodeType'):
157     def global_cache_type_e_is_String(e):
158         t = type(e)
159         return t is StringType \
160             or t is UnicodeType \
161             or (t is InstanceType and isinstance(e, UserString))
162 else:
163     def global_cache_type_e_is_String(e):
164         t = type(e)
165         return t is StringType \
166             or (t is InstanceType and isinstance(e, UserString))
167
168
169
170 # Alternative that uses a myType() function to map the User* objects
171 # to their corresponding underlying types.
172
173 instanceTypeMap = {
174     UserDict : types.DictType,
175     UserList : types.ListType,
176     UserString : types.StringType,
177 }
178
179 if hasattr(types, 'UnicodeType'):
180     def myType(obj):
181         t = type(obj)
182         if t is types.InstanceType:
183             t = instanceTypeMap.get(obj.__class__, t)
184         elif t is types.UnicodeType:
185             t = types.StringType
186         return t
187 else:
188     def myType(obj):
189         t = type(obj)
190         if t is types.InstanceType:
191             t = instanceTypeMap.get(obj.__class__, t)
192         return t
193
194 def myType_is_Dict(e):
195     return myType(e) is types.DictType
196
197 def myType_is_List(e):
198     return myType(e) is types.ListType
199
200 def myType_is_String(e):
201     return myType(e) is types.StringType
202
203
204
205
206 def Func01(obj):
207     """original_is_String"""
208     for i in IterationList:
209         original_is_String(obj)
210
211 def Func02(obj):
212     """original_is_List"""
213     for i in IterationList:
214         original_is_List(obj)
215
216 def Func03(obj):
217     """original_is_Dict"""
218     for i in IterationList:
219         original_is_Dict(obj)
220
221 def Func04(obj):
222     """checkInstanceType_is_String"""
223     for i in IterationList:
224         checkInstanceType_is_String(obj)
225
226 def Func05(obj):
227     """checkInstanceType_is_List"""
228     for i in IterationList:
229         checkInstanceType_is_List(obj)
230
231 def Func06(obj):
232     """checkInstanceType_is_Dict"""
233     for i in IterationList:
234         checkInstanceType_is_Dict(obj)
235
236 def Func07(obj):
237     """cache_type_e_is_String"""
238     for i in IterationList:
239         cache_type_e_is_String(obj)
240
241 def Func08(obj):
242     """cache_type_e_is_List"""
243     for i in IterationList:
244         cache_type_e_is_List(obj)
245
246 def Func09(obj):
247     """cache_type_e_is_Dict"""
248     for i in IterationList:
249         cache_type_e_is_Dict(obj)
250
251 def Func10(obj):
252     """global_cache_type_e_is_String"""
253     for i in IterationList:
254         global_cache_type_e_is_String(obj)
255
256 def Func11(obj):
257     """global_cache_type_e_is_List"""
258     for i in IterationList:
259         global_cache_type_e_is_List(obj)
260
261 def Func12(obj):
262     """global_cache_type_e_is_Dict"""
263     for i in IterationList:
264         global_cache_type_e_is_Dict(obj)
265
266 #def Func13(obj):
267 #    """myType_is_String"""
268 #    for i in IterationList:
269 #        myType_is_String(obj)
270 #
271 #def Func14(obj):
272 #    """myType_is_List"""
273 #    for i in IterationList:
274 #        myType_is_List(obj)
275 #
276 #def Func15(obj):
277 #    """myType_is_Dict"""
278 #    for i in IterationList:
279 #        myType_is_Dict(obj)
280
281
282
283 # Data to pass to the functions on each run.  Each entry is a
284 # three-element tuple:
285 #
286 #   (
287 #       "Label to print describing this data run",
288 #       ('positional', 'arguments'),
289 #       {'keyword' : 'arguments'},
290 #   ),
291
292 class A:
293     pass
294
295 Data = [
296     (
297         "String",
298         ('',),
299         {},
300     ),
301     (
302         "List",
303         ([],),
304         {},
305     ),
306     (
307         "Dict",
308         ({},),
309         {},
310     ),
311     (
312         "UserString",
313         (UserString(''),),
314         {},
315     ),
316     (
317         "UserList",
318         (UserList([]),),
319         {},
320     ),
321     (
322         "UserDict",
323         (UserDict({}),),
324         {},
325     ),
326     (
327         "Object",
328         (A(),),
329         {},
330     ),
331 ]
332
333 # Local Variables:
334 # tab-width:4
335 # indent-tabs-mode:nil
336 # End:
337 # vim: set expandtab tabstop=4 shiftwidth=4: