Skip to content

Instantly share code, notes, and snippets.

@suguby
Created February 10, 2010 12:37
Show Gist options
  • Save suguby/300268 to your computer and use it in GitHub Desktop.
Save suguby/300268 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import time
def add(x,y):
return x+y
def max(x,y):
if x<y: return y
return x
def min(x,y):
if x>y: return y
return x
def subtraction_square(x,y):
return pow(x-y, 2)
def get_stat(meas):
meas_count = len(meas)
average = reduce(add, meas) / meas_count
deviation = pow( reduce(add, map(lambda x:subtraction_square(x,average), meas) ) / ( meas_count - 1 ), 0.5)
variation = round( ( deviation / average ) * 100, 2 )
return average, deviation, variation
def replace_at_pos(line, pos, symb):
ll = len(line)
if pos >= ll: pos = ll - 1
if pos < 0: pos = 0
if pos==0:
return symb+line[1:]
return line[:pos-1]+symb+line[pos:]
def test_perf(funct_list, params, iter_count = 300):
meas, results, funct_name_max_size = {}, {}, 0
for funct in funct_list:
# for funct in [suguby]:
funct_name = funct.__name__
if len(funct_name) > funct_name_max_size: funct_name_max_size = len(funct_name)
begin = time.time()
res = funct(params)
meas[funct_name] = time.time() - begin
res = str(res)
if results and res not in results.values():
print 'warning! funct %s produce different result !!! ' % funct_name
results[funct_name] = res
min_time = reduce(min, meas.values())
# one_meas_time = 0.1 / iter_count # сколько должно длится измерение времени для одной функции, что бы всего было затрачено 3 секунды
one_meas_time = 3.0 / iter_count # сколько должно длится измерение времени для одной функции, что бы всего было затрачено 3 секунды
if min_time < one_meas_time: # если время выполнения меньше времени на одно измерение, то увеличиваем кол-во повторов
iters_for_meas = int( one_meas_time / min_time)
else:
iters_for_meas = 1 # если время больше - то что делать, будем ждать...
meas = {}
for i in range(iter_count):
print '\r', 'doing %04i measurement...' % i,
sys.stdout.flush()
for funct in funct_list:
funct_name = funct.__name__
begin = time.time()
for j in range(iters_for_meas):
funct(params)
elapsed = time.time() - begin
try:
meas[funct_name].append(elapsed)
except:
meas[funct_name]=[elapsed]
print '\r', ' '*60
min_time, max_time = 10000, 0
for funct_name in meas:
for val in meas[funct_name]:
if val < min_time: min_time = val
if val > max_time: max_time = val
scale_len, scale_secs = 60, max_time - min_time
symb_sec = scale_secs / scale_len
cells, max_cells = {}, {}
for funct_name in meas:
cells[funct_name] = [0,] * scale_len
max_cell = 0
for val in meas[funct_name]:
shift = val - min_time
pos = int( shift / symb_sec )
if pos >= scale_len: pos = scale_len - 1
cells[funct_name][pos] += 1
for cell in cells[funct_name]:
if cell > max_cell: max_cell = cell
max_cells[funct_name] = max_cell
average = [(funct_name, get_stat(meas[funct_name])) for funct_name in meas]
average = sorted(average, key = lambda x: x[1]) # пригодился алгоритм со второго спринта :)))
# определяем степень округления
# rest = str(min_time - round(min_time))[2:]
# round_by = abs( rest.rfind('0') ) + 4
round_by = 6
format = '%.'+str(round_by)+'f'
graph_elems = ['.', '=', '#', '^']
print "total %i measurements, %i function call(s) for one measurement " % (iter_count, iters_for_meas)
print ' '*(funct_name_max_size + scale_len + 8), 'average\tdeviation\tvariation'
for funct_name, funct_meas in average:
print '-'*3, ' ', funct_name.ljust(funct_name_max_size+1, ' '),
average, deviation, variation = funct_meas
shift = average - min_time
pos_average = int( shift / symb_sec )
if pos_average >= scale_len: pos_average = scale_len - 1
max_cell = float( max_cells[funct_name] )
out = ''
for i in range(scale_len): # ____.-=#^
if i == pos_average:
out += '|'
continue
val = float(cells[funct_name][i]) / max_cell
if val > 0.75:
out += graph_elems[3]
elif val > 0.5:
out += graph_elems[2]
elif val > 0.25:
out += graph_elems[1]
elif val > 0:
out += graph_elems[0]
else:
out += '_'
print out, format % average, '\t', format % deviation, '\t', variation, '%'
secs_from = format % min_time
secs_till = format % max_time
print ' '*(funct_name_max_size + 7),
print '|'+secs_from.ljust(len(secs_from)),
print 'seconds'.center(scale_len - len(secs_from) - len(secs_till) - 4),
print secs_till.rjust(len(secs_till))+'|'
print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment