Время выполнения кода: как правильно СУШИТЬ несколько раз это выполнение?
Давайте предположим, что мы хотим использовать timeit для тестирования производительности с разными входами.
Очевидный, не сухой способ будет выглядеть примерно так:
import timeit
# define functions to test
def some_list_operation_A(lst):
...
def some_list_operation_B(lst):
...
# create different lists (different input) to test the functions with
...
inputs = [lsta, lstb, lstc, ...]
# measure performance with first function
num = 10
t_lsta = timeit.timeit("some_list_operation_A(lsta)",
setup="from __main__ import some_list_operation_A, lsta",
number=num)
t_lstb = timeit.timeit("some_list_operation_A(lstb)",
setup="from __main__ import some_list_operation_A, lstb",
number=num)
t_lstc = timeit.timeit("some_list_operation_A(lstc)",
setup="from __main__ import some_list_operation_A, lstc",
number=num)
...
# print results & do some comparison stuff
for res in [t_lsta, t_lstb, t_lstc, ...]:
print("{:.4f}s".format(res))
...
# do this ALL OVER AGAIN for 'some_list_operation_B'
...
# print new results
# do this ALL OVER AGAIN for 'some_list_operation_C'
# ...I guess you'll got the point
...
Я думаю, должно быть очень ясно, что это был бы действительно уродливый способ измерить производительность различных функций для разных входных данных.
В настоящее время я делаю что-то вроде этого:
...
inputs = dict()
inputs["lsta"] = lsta
inputs["lstb"] = lstb
inputs["lstc"] = lstc
for f in ["some_list_operation_A", "some_list_operation_B", ...]:
r = dict() # results
for key, val in inputs.iteritems():
r[key] = timeit.timeit("{}(inputs[{}])".format(f, key),
setup="from __main__ import {}, inputs".format(f),
number=num
# evaluate results 'r' for function 'f' here
# (includes a comparison of the results -
# that's why I save them in 'r')
...
# loop moves on to next function 'f'
В основном я использую .format
здесь, чтобы вставить имя функции и вставить правильные данные inputs[key]
, После .format
заполняет все {}
результат один правильный stmt
строка timeit
,
Хотя это намного короче, чем очевидное решение, не являющееся сухим, оно также менее читабельно и больше похоже на взлом, не так ли?
Что будет подходящим сухим решением для таких проблем?
Я также подумал о том, чтобы просто синхронизировать функции с декораторами (это было бы здорово?!) - но у меня ничего не получилось: декоратор должен не только печатать результат. В моем # evaluate results 'r'
-шаг Я не только печатаю результаты, но и сравниваю их: например, вычисление относительных различий и прочее. Таким образом, мне нужно, чтобы декоратор что-то возвращал, чтобы сравнивать результаты для каждого прогона...
Может кто-то намекнуть мне в правильном направлении для чистого, питонического решения? Я хотел бы иметь более красивый / идеоматичный код... и особенно: более короткий код!