Created
February 10, 2010 12:37
-
-
Save suguby/300268 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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))+'|' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment