简体   繁体   English

使用timeit时无法将列表传递给此Python函数

[英]Unable to pass list to this Python function when using timeit

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. 问题在于运行时间不会变化,这是因为每次运行时,函数quad引用为空的global subseq How can I pass this sub-sequence correctly to this function? 如何正确地将此子序列传递给此函数?

PS: 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. PS:我也可以使用其他工具来完成这项工作,只要它可以为我提供该函数每次迭代的确切运行时间(就使用的CPU时间而言)。

By default, Python thinks that subseq is a variable local to your function. 默认情况下,Python认为subseq是函数局部变量。 This local name shadows the global variable that you're passing a parameter to the timeit timer. 此本地名称隐藏了将参数传递给timeit计时器的全局变量。

To make the assignment operation globally-visible, you need to declare the subseq variable as global before using it in the function: 为了使赋值操作在全局范围内可见,需要在函数中使用subseq变量之前将其声明为global变量:

def plot_func (name):
    global subseq
    print('\n')
    for i in range(len(seq)):
        subseq = seq[0:i+1]

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 由于您的目标只是衡量算法以检查结果,因此我建议您在timeit范围内运行所有内容,如下所示

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. 这样,timeit将在其作用域内设置所有内容,并在其中运行您定义的函数。
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 重要的是要注意,从print语句开始到运行所花费的时间也将被计算在内,但这不会显着改变结果,最重要的是,不会使它失去二次上下文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM