http://scons.tigris.org/issues/show_bug.cgi?id=2329
[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 isinstance(seq, str):
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 = dict
64 ListType = list
65 StringType = str
66 try: unicode
67 except NameError:
68     UnicodeType = None
69 else:
70     UnicodeType = unicode
71
72
73 # The original implementations, pretty straightforward checks for the
74 # type of the object and whether it's an instance of the corresponding
75 # User* type.
76
77 def original_is_Dict(e):
78     return isinstance(e, dict) or isinstance(e, UserDict)
79
80 def original_is_List(e):
81     return isinstance(e, list) or isinstance(e, UserList)
82
83 if UnicodeType is not None:
84     def original_is_String(e):
85         return isinstance(e, str) \
86             or isinstance(e, unicode) \
87             or isinstance(e, UserString)
88 else:
89     def original_is_String(e):
90         return isinstance(e, str) or isinstance(e, UserString)
91
92
93
94 # New candidates that explicitly check for whether the object is an
95 # InstanceType before calling isinstance() on the corresponding User*
96 # type.
97
98 def checkInstanceType_is_Dict(e):
99     return isinstance(e, dict) or \
100            (isinstance(e, types.InstanceType) and isinstance(e, UserDict))
101
102 def checkInstanceType_is_List(e):
103     return isinstance(e, list) \
104         or (isinstance(e, types.InstanceType) and isinstance(e, UserList))
105
106 if UnicodeType is not None:
107     def checkInstanceType_is_String(e):
108         return isinstance(e, str) \
109             or isinstance(e, unicode) \
110             or (isinstance(e, types.InstanceType) and isinstance(e, UserString))
111 else:
112     def checkInstanceType_is_String(e):
113         return isinstance(e, str) \
114             or (isinstance(e, types.InstanceType) and isinstance(e, UserString))
115
116
117
118 # Improved candidates that cache the type(e) result in a variable
119 # before doing any checks.
120
121 def cache_type_e_is_Dict(e):
122     t = type(e)
123     return t is dict or \
124            (t is types.InstanceType and isinstance(e, UserDict))
125
126 def cache_type_e_is_List(e):
127     t = type(e)
128     return t is list \
129         or (t is types.InstanceType and isinstance(e, UserList))
130
131 if UnicodeType is not None:
132     def cache_type_e_is_String(e):
133         t = type(e)
134         return t is str \
135             or t is unicode \
136             or (t is types.InstanceType and isinstance(e, UserString))
137 else:
138     def cache_type_e_is_String(e):
139         t = type(e)
140         return t is str \
141             or (t is types.InstanceType and isinstance(e, UserString))
142
143
144
145 # Improved candidates that cache the type(e) result in a variable
146 # before doing any checks, but using the global names for
147 # DictType, ListType and StringType.
148
149 def global_cache_type_e_is_Dict(e):
150     t = type(e)
151     return t is DictType or \
152            (t is InstanceType and isinstance(e, UserDict))
153
154 def global_cache_type_e_is_List(e):
155     t = type(e)
156     return t is ListType \
157         or (t is InstanceType and isinstance(e, UserList))
158
159 if UnicodeType is not None:
160     def global_cache_type_e_is_String(e):
161         t = type(e)
162         return t is StringType \
163             or t is UnicodeType \
164             or (t is InstanceType and isinstance(e, UserString))
165 else:
166     def global_cache_type_e_is_String(e):
167         t = type(e)
168         return t is StringType \
169             or (t is InstanceType and isinstance(e, UserString))
170
171
172
173 # Alternative that uses a myType() function to map the User* objects
174 # to their corresponding underlying types.
175
176 instanceTypeMap = {
177     UserDict : dict,
178     UserList : list,
179     UserString : str,
180 }
181
182 if UnicodeType is not None:
183     def myType(obj):
184         t = type(obj)
185         if t is types.InstanceType:
186             t = instanceTypeMap.get(obj.__class__, t)
187         elif t is unicode:
188             t = str
189         return t
190 else:
191     def myType(obj):
192         t = type(obj)
193         if t is types.InstanceType:
194             t = instanceTypeMap.get(obj.__class__, t)
195         return t
196
197 def myType_is_Dict(e):
198     return myType(e) is dict
199
200 def myType_is_List(e):
201     return myType(e) is list
202
203 def myType_is_String(e):
204     return myType(e) is str
205
206
207
208
209 def Func01(obj):
210     """original_is_String"""
211     for i in IterationList:
212         original_is_String(obj)
213
214 def Func02(obj):
215     """original_is_List"""
216     for i in IterationList:
217         original_is_List(obj)
218
219 def Func03(obj):
220     """original_is_Dict"""
221     for i in IterationList:
222         original_is_Dict(obj)
223
224 def Func04(obj):
225     """checkInstanceType_is_String"""
226     for i in IterationList:
227         checkInstanceType_is_String(obj)
228
229 def Func05(obj):
230     """checkInstanceType_is_List"""
231     for i in IterationList:
232         checkInstanceType_is_List(obj)
233
234 def Func06(obj):
235     """checkInstanceType_is_Dict"""
236     for i in IterationList:
237         checkInstanceType_is_Dict(obj)
238
239 def Func07(obj):
240     """cache_type_e_is_String"""
241     for i in IterationList:
242         cache_type_e_is_String(obj)
243
244 def Func08(obj):
245     """cache_type_e_is_List"""
246     for i in IterationList:
247         cache_type_e_is_List(obj)
248
249 def Func09(obj):
250     """cache_type_e_is_Dict"""
251     for i in IterationList:
252         cache_type_e_is_Dict(obj)
253
254 def Func10(obj):
255     """global_cache_type_e_is_String"""
256     for i in IterationList:
257         global_cache_type_e_is_String(obj)
258
259 def Func11(obj):
260     """global_cache_type_e_is_List"""
261     for i in IterationList:
262         global_cache_type_e_is_List(obj)
263
264 def Func12(obj):
265     """global_cache_type_e_is_Dict"""
266     for i in IterationList:
267         global_cache_type_e_is_Dict(obj)
268
269 #def Func13(obj):
270 #    """myType_is_String"""
271 #    for i in IterationList:
272 #        myType_is_String(obj)
273 #
274 #def Func14(obj):
275 #    """myType_is_List"""
276 #    for i in IterationList:
277 #        myType_is_List(obj)
278 #
279 #def Func15(obj):
280 #    """myType_is_Dict"""
281 #    for i in IterationList:
282 #        myType_is_Dict(obj)
283
284
285
286 # Data to pass to the functions on each run.  Each entry is a
287 # three-element tuple:
288 #
289 #   (
290 #       "Label to print describing this data run",
291 #       ('positional', 'arguments'),
292 #       {'keyword' : 'arguments'},
293 #   ),
294
295 class A:
296     pass
297
298 Data = [
299     (
300         "String",
301         ('',),
302         {},
303     ),
304     (
305         "List",
306         ([],),
307         {},
308     ),
309     (
310         "Dict",
311         ({},),
312         {},
313     ),
314     (
315         "UserString",
316         (UserString(''),),
317         {},
318     ),
319     (
320         "UserList",
321         (UserList([]),),
322         {},
323     ),
324     (
325         "UserDict",
326         (UserDict({}),),
327         {},
328     ),
329     (
330         "Object",
331         (A(),),
332         {},
333     ),
334 ]
335
336 # Local Variables:
337 # tab-width:4
338 # indent-tabs-mode:nil
339 # End:
340 # vim: set expandtab tabstop=4 shiftwidth=4: