So I am making a program that shows how long each sorting algorithm takes to run on a specific list of unsorted numbers. I created a decorator function as follows
def timed(func):
def wrapper(*args, **kwargs):
start = datetime.now()
val = func(*args, **kwargs)
delta = datetime.now() - start
print(delta.microseconds / 1000)
return val
return wrapper
Now this decorator works for all iterative functions as expected. However, the problem is with recursive functions. Take merge sort for example:
def _merge_sorted(l, r):
i = j = 0
temp = []
while i < len(l) and j < len(r):
if l[i] <= r[j]:
temp.append(l[i])
i += 1
else:
temp.append(r[j])
j += 1
temp.extend(l[i::])
temp.extend(r[j::])
return temp
@timed
def merge(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge(arr[:mid])
right = merge(arr[mid:])
return _merge_sorted(left, right)
When I call merge() on a list, instead of printing the time once, the program prints the time for what seems like every call in the call stack of this recursion. So the output for [5,4,3,2,1] is
0.001
0.001
0.032
0.001
0.001
0.0
0.006
0.013
0.054
I know the problem is caused by the decorator printing for each call in the call stack, but I can't find a way to fix this behavior to make it print the total time taken and make it work for both iterative and recursive functions.