Reputation: 5417
I wrote a small script to generate the running times of a function with varying input. My intent was to plot the numbers and prove to myself that the function indeed had a quadratic running time. Here's the code:
import timeit
seq = [875011, 549220, 400865, 913974, 699921, 108386, 328934, 593902, 805659, 916502, 597662]
subseq = []
num = 1000000 # How many times the algorithm must run
# Quadratic running time
def quad (S):
n = len(S)
A = [0] * n
for j in range(n):
total = 0
for i in range(j+1):
total += S[i]
A[j] = total / (j+1)
return A
def plot_func (name):
print('\n')
for i in range(len(seq)):
subseq = seq[0:i+1]
t = timeit.Timer('{}(subseq)'.format(name), 'from __main__ import {}, subseq'.format(name))
print(t.timeit(number=num))
plot_func('quad')
The problem is that the running time doesn't vary, and that's because every time it runs, the function quad
refers to the global subseq
, which is empty. How can I pass this sub-sequence correctly to this function?
P.S.: I'm also fine using another tool for this job, as long as it can give me the exact running time (in terms of CPU time used) of each iteration of the function.
Upvotes: 0
Views: 218
Reputation: 59284
To separate your code with code you want to measure usually is not a good idea.
As your goal is just measure your algorithm to check results, I recommend you to run everything inside timeit
scope, like the following
import timeit
num = 1000000 # How many times the algorithm must run
setup = """
seq = [875011, 549220, 400865, 913974, 699921, 108386, 328934, 593902, 805659, 916502, 597662]
subseq = []
# Quadratic running time
def quad (S):
n = len(S)
A = [0] * n
for j in range(n):
total = 0
for i in range(j+1):
total += S[i]
A[j] = total / (j+1)
return A
"""
run_function = """
def plot_func (name):
print('\n')
for i in range(len(seq)):
subseq = seq[0:i+1]
print(t.timeit(number=num))
plot_func('quad')
"""
timeit.timeit(stmt=run_function, setup=setup, number=num)
This way, timeit will setup everything inside its scope and run your defined function within it as well.
It is important to notice that the time taken from print
statement to run will also be counted, however, that will not alter significantly the results and most importantly, will not make it lose its quadratic context
Upvotes: 1
Reputation: 8537
By default, Python thinks that subseq
is a variable local to your function. This local name shadows the global variable that you're passing a parameter to the timeit
timer.
To make the assignment operation globally-visible, you need to declare the subseq
variable as global
before using it in the function:
def plot_func (name):
global subseq
print('\n')
for i in range(len(seq)):
subseq = seq[0:i+1]
Upvotes: 1