简体   繁体   English

如何让 Python timeit 模块不重复循环中的最后一次迭代

[英]How to get Python timeit module to not repeat the last iteration within a loop

I am doing some load testing using timeit.我正在使用 timeit 进行一些负载测试。 I am looping through a list.我正在遍历一个列表。 In everything I have tried, timeit repeats the last value in the list 3 times.在我尝试过的所有内容中, timeit 都会重复列表中的最后一个值 3 次。 I know that repeat defaults to 3. I've tried not using repeat.我知道重复默认为 3。我试过不使用重复。 I've tried using repeat, but setting repeat to 0. What I want is either 0 repeats, or a repeat that picks up the correct parameter instead of repeating the last parameter 3 times.我试过使用repeat,但将repeat 设置为0。我想要的是0 次重复,或者选择正确参数而不是重复最后一个参数3 次的重复。 I'll show you what I've tried, and then the expected results, and the actual results.我将向您展示我的尝试,然后是预期结果和实际结果。

My module is named z_sandbox.py, and I am calling this in the module, by executing within VS Code.我的模块名为 z_sandbox.py,我通过在 VS Code 中执行在模块中调用它。 I am not using the command line.我没有使用命令行。

I've tried three different options:我尝试了三种不同的选择:

Option #1: timeit.Timer, with no repeats specified.选项#1:timeit.Timer,不指定重复。

import timeit
params = ["param1", "param2", "param3"]
print("*****START*****")
for param in params:  
    print('STARTING: %s ' % (param))   
    timeit.Timer(
        stmt="print('%s ' % (z_sandbox.param))",
        setup="import z_sandbox"
    ).timeit(number=3)
print("*****DONE*****")

Expected Results:预期成绩:

In the above I am not using a repeat, so I would expect no repeats, and exactly 3 executions of each statement, for a total of 9 executions.在上面我没有使用重复,所以我希望没有重复,并且每个语句正好执行 3 次,总共执行 9 次。

Expected:预期的:

*****START*****
STARTING: param1
param1
param1
param1
STARTING: param2
param2
param2
param2
STARTING: param3
param3
param3
param3
*****DONE*****

Actual:实际的:

*****START*****
STARTING: param1
*****START*****
STARTING: param1
param1
param1
param1
STARTING: param2
param2
param2
param2
STARTING: param3
param3
param3
param3
*****DONE*****
param3
param3
param3
STARTING: param2
param3
param3
param3
STARTING: param3
param3
param3
param3
*****DONE*****

Questions: Why is "STARTING: param1" printed twice at the top?问题:为什么“STARTING: param1”在顶部打印两次? Why are the last 9 executions all param3, instead of 3 executions of each parameter?为什么最后 9 次执行都是 param3,而不是每个参数执行 3 次? Why in the repeats is there "STARTING: param2" but then the actual execution was for param3?为什么在重复中有 "STARTING: param2" 但实际执行是针对 param3 的? How do I get my expected results, which is no repeats?我如何获得预期的结果,没有重复?

Option #2: timeit.repeat, with 1 repeat specified.选项 #2:timeit.repeat,指定 1 次重复。

timeit.repeat(
    stmt="print('%s ' % (z_sandbox.param))",
    setup="import z_sandbox",
    repeat=1,
    number=3
)

Above produces same results as Option #1.以上产生与选项 #1 相同的结果。

Option #3: timeit.repeat, with 0 repeat specified.选项 #3:timeit.repeat,指定 0 重复。

timeit.repeat(
    stmt="print('%s ' % (z_sandbox.param))",
    setup="import z_sandbox",
    repeat=0,
    number=3
)

Above produces nothing at all.以上根本不产生任何东西。

Variation on each of above以上各项的变化

I also tried printing the output to a file, instead of to a screen.我还尝试将输出打印到文件,而不是屏幕。 There is no difference in the output.输出没有区别。

How do I get my expected results, which is no repeats?我如何获得预期的结果,没有重复?

You can pass a callable as stmt to Timer .您可以将 callable 作为stmt传递给Timer

timeit.Timer(stmt=lambda: print('%s ' % (param,))).timeit(number=3)

The issue with your code was that it had no main import guard to prevent the main code from occurring when the module is imported a second time.您的代码的问题在于它没有主要的导入保护来防止第二次导入模块时出现主代码。 The thing about main modules is that they can be loaded twice.关于主模块的事情是它们可以被加载两次。 Once as __main__ and once under their module name.一次作为__main__ ,一次在他们的模块名称下。

Your code could be fixed by doing:您可以通过执行以下操作来修复您的代码:

import timeit
params = ["param1", "param2", "param3"]
if __name__=="__main__":
    print("*****START*****")
    for idx, param in enumerate(params): 
        print('STARTING: %s ' % (param,)) 
        timeit.Timer(stmt="print('%%s ' %% (z_sandbox.params[%r]))" % (idx,), setup="import z_sandbox" ).timeit(number=3)
    print("*****DONE*****")

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

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