1
2
3
4 """Benchmarking.
5
6 Run each test 3 times and get median value.
7 Using 10K array as base test time.
8
9 Each other test compared with base with next formula::
10
11 Tc * Nb
12 q = ---------
13 Tb * Nc
14
15 Here:
16
17 * Tc - execution time of current test
18 * Tb - execution time of base
19 * Nb - array size of base (10K)
20 * Nc - array size of current test
21
22 If resulting value is ``q <= 1.0`` it's the best possible result,
23 i.e. time increase proportionally to array size.
24 """
25
26 from cStringIO import StringIO
27 import gc
28 import sys
29 import time
30
31 import intelhex
32
33
42
44 """Run func with argument fobj and measure execution time.
45 @param func: function for test
46 @param fobj: data for test
47 @return: execution time
48 """
49 gc.disable()
50 try:
51 begin = time.time()
52 func(fobj)
53 end = time.time()
54 finally:
55 gc.enable()
56 return end - begin
57
59 """Run each test N times.
60 @param func: function for test
61 @param hexstr: string with content of hex file to read
62 @param n: times to repeat.
63 @return: (median time, times list)
64 """
65 assert n > 0
66 times = []
67 for i in xrange(n):
68 sio = StringIO(hexstr)
69 times.append(run_test(func, sio))
70 sio.close()
71 t = median(times)
72 return t, times
73
75 """Run each test N times.
76 @param func: function for test
77 @param n: times to repeat.
78 @return: (median time, times list)
79 """
80 assert n > 0
81 times = []
82 for i in xrange(n):
83 sio = StringIO()
84 times.append(run_test(func, sio))
85 sio.close()
86 t = median(times)
87 return t, times
88
90 """Return time coefficient relative to base numbers.
91 @param tc: current test time
92 @param nc: current test data size
93 @param tb: base test time
94 @param nb: base test data size
95 @return: time coef.
96 """
97 tc = float(tc)
98 nc = float(nc)
99 tb = float(tb)
100 nb = float(nb)
101 q = (tc * nb) / (tb * nc)
102 return q
103
105 """Create test data on given pattern.
106 @param n1: size of first part of array at base address 0.
107 @param offset: offset for second part of array.
108 @param n2: size of second part of array at given offset.
109 @return: (overall size, hex file, IntelHex object)
110 """
111
112 ih = intelhex.IntelHex()
113 addr = 0
114 for i in xrange(n1):
115 ih[addr] = addr % 256
116 addr += 1
117 addr += offset
118 for i in xrange(n2):
119 ih[addr] = addr % 256
120 addr += 1
121
122 sio = StringIO()
123 ih.write_hex_file(sio)
124 hexstr = sio.getvalue()
125 sio.close()
126
127 return n1+n2, hexstr, ih
128
132
135
138
141
144
145
147 """Measure execution time helper."""
148
149 data_set = [
150
151 ('base 10K', get_base_10K),
152 ('100K', get_100K),
153 ('1M', get_1M),
154 ('100K+100K', get_100K_100K),
155 ('0+100K', get_0_100K),
156 ]
157
158 - def __init__(self, n=3, read=True, write=True):
159 self.n = n
160 self.read = read
161 self.write = write
162 self.results = []
163
165 """Do measuring of read and write operations.
166 @param data: 3-tuple from get_test_data
167 @return: (time readhex, time writehex)
168 """
169 _unused, hexstr, ih = data
170 tread, twrite = 0.0, 0.0
171 if self.read:
172 tread = run_readtest_N_times(intelhex.IntelHex, hexstr, self.n)[0]
173 if self.write:
174 twrite = run_writetest_N_times(ih.write_hex_file, self.n)[0]
175 return tread, twrite
176
182
184 if to_file is None:
185 to_file = sys.stdout
186
187 base_title, base_times, base_n = self.results[0]
188 base_read, base_write = base_times
189 read_report = ['%-10s\t%7.3f' % (base_title, base_read)]
190 write_report = ['%-10s\t%7.3f' % (base_title, base_write)]
191
192 for item in self.results[1:]:
193 cur_title, cur_times, cur_n = item
194 cur_read, cur_write = cur_times
195 if self.read:
196 qread = time_coef(cur_read, cur_n,
197 base_read, base_n)
198 read_report.append('%-10s\t%7.3f\t%7.3f' % (cur_title,
199 cur_read,
200 qread))
201 if self.write:
202 qwrite = time_coef(cur_write, cur_n,
203 base_write, base_n)
204 write_report.append('%-10s\t%7.3f\t%7.3f' % (cur_title,
205 cur_write,
206 qwrite))
207 if self.read:
208 to_file.write('Read operation:\n')
209 to_file.write('\n'.join(read_report))
210 to_file.write('\n\n')
211 if self.write:
212 to_file.write('Write operation:\n')
213 to_file.write('\n'.join(write_report))
214 to_file.write('\n\n')
215
216
217 HELP = """\
218 Usage: python _bench.py [OPTIONS]
219
220 Options:
221 -h this help
222 -n N repeat tests N times
223 -r run only tests for read operation
224 -w run only tests for write operation
225
226 If option -r or -w is not specified then all tests will be run.
227 """
228
229
230 -def main(argv=None):
231 """Main function to run benchmarks.
232 @param argv: command-line arguments.
233 @return: exit code (0 is OK).
234 """
235 import getopt
236
237
238 test_read = None
239 test_write = None
240 n = 3
241
242 if argv is None:
243 argv = sys.argv[1:]
244
245 try:
246 opts, args = getopt.getopt(argv, 'hn:rw', [])
247
248 for o,a in opts:
249 if o == '-h':
250 print HELP
251 return 0
252 elif o == '-n':
253 n = int(a)
254 elif o == '-r':
255 test_read = True
256 elif o == '-w':
257 test_write = True
258
259 if args:
260 raise getopt.GetoptError('Arguments are not used.')
261 except getopt.GetoptError, msg:
262 print str(msg)
263 return 1
264
265 if (test_read, test_write) == (None, None):
266 test_read = test_write = True
267
268 m = Measure(n, test_read, test_write)
269 m.measure_all()
270 m.print_report()
271
272 return 0
273
274
275 if __name__ == '__main__':
276 sys.exit(main(sys.argv[1:]))
277
278
279 """
280
281 Some Results
282 ************
283
284
285 21/04/2007 revno.40
286 Python 2.5 @ Windows XP, Intel Celeron M CPU 430 @ 1.73GHz
287
288 Read operation:
289 base 10K 0.031
290 100K 0.360 1.161
291 1M 3.500 1.129
292 100K+100K 0.719 1.160
293 0+100K 0.360 1.161
294
295 Write operation:
296 base 10K 0.031
297 100K 0.297 0.958
298 1M 2.953 0.953
299 100K+100K 1.328 2.142
300 0+100K 0.312 1.006
301
302
303 21/04/2007 revno.46
304 Python 2.5 @ Windows XP, Intel Celeron M CPU 430 @ 1.73GHz
305
306 Read operation:
307 base 10K 0.016
308 100K 0.203 1.269
309 1M 2.000 1.250
310 100K+100K 0.422 1.319
311 0+100K 0.203 1.269
312
313 Write operation:
314 base 10K 0.031
315 100K 0.297 0.958
316 1M 2.969 0.958
317 100K+100K 1.328 2.142
318 0+100K 0.312 1.006
319
320
321 22/04/2007 revno.48
322 Python 2.5 @ Windows XP, Intel Celeron M CPU 430 @ 1.73GHz
323
324 Read operation:
325 base 10K 0.016
326 100K 0.187 1.169
327 1M 1.891 1.182
328 100K+100K 0.406 1.269
329 0+100K 0.188 1.175
330
331 Write operation:
332 base 10K 0.031
333 100K 0.296 0.955
334 1M 2.969 0.958
335 100K+100K 1.328 2.142
336 0+100K 0.312 1.006
337
338
339 19/08/2008 revno.72
340 Python 2.5.2 @ Windows XP, Intel Celeron M CPU 430 @ 1.73GHz
341
342 Read operation:
343 base 10K 0.016
344 100K 0.171 1.069
345 1M 1.734 1.084
346 100K+100K 0.375 1.172
347 0+100K 0.172 1.075
348
349 Write operation:
350 base 10K 0.016
351 100K 0.156 0.975
352 1M 1.532 0.957
353 100K+100K 0.344 1.075
354 0+100K 0.156 0.975
355
356 """
357