Package intelhex :: Module bench
[hide private]
[frames] | no frames]

Source Code for Module intelhex.bench

  1  #!/usr/bin/python 
  2  # (c) Alexander Belchenko, 2007, 2009 
  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   
34 -def median(values):
35 """Return median value for the list of values. 36 @param values: list of values for processing. 37 @return: median value. 38 """ 39 values.sort() 40 n = int(len(values) / 2) 41 return values[n]
42
43 -def run_test(func, fobj):
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
58 -def run_readtest_N_times(func, hexstr, n):
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
74 -def run_writetest_N_times(func, n):
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
89 -def time_coef(tc, nc, tb, nb):
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
104 -def get_test_data(n1, offset, n2):
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 # make IntelHex object 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 # make hex file 122 sio = StringIO() 123 ih.write_hex_file(sio) 124 hexstr = sio.getvalue() 125 sio.close() 126 # 127 return n1+n2, hexstr, ih
128
129 -def get_base_10K():
130 """Base 10K""" 131 return get_test_data(10000, 0, 0)
132
133 -def get_100K():
134 return get_test_data(100000, 0, 0)
135
136 -def get_100K_100K():
137 return get_test_data(100000, 1000000, 100000)
138
139 -def get_0_100K():
140 return get_test_data(0, 1000000, 100000)
141
142 -def get_1M():
143 return get_test_data(1000000, 0, 0)
144 145
146 -class Measure(object):
147 """Measure execution time helper.""" 148 149 data_set = [ 150 # (data name, getter) 151 ('base 10K', get_base_10K), # first should be base numbers 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
164 - def measure_one(self, data):
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
177 - def measure_all(self):
178 for name, getter in self.data_set: 179 data = getter() 180 times = self.measure_one(data) 181 self.results.append((name, times, data[0]))
182
183 - def print_report(self, to_file=None):
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 # default values 238 test_read = None 239 test_write = None 240 n = 3 # number of repeat 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