运行时间:打印计数是一步吗?

时间:2013-07-14 20:10:35

标签: python performance

假设我有一个函数,我想分析确切步数的运行时间:

def function(L):
    print ("Hello")
    i = 0                 # 1 step
    while i < len(L):     # 3 steps
        print (L[i] + 1)
        i += 2            # 2 steps
    print ("Goodbye")

我想知道印刷品陈述是否算作一个步骤?

2 个答案:

答案 0 :(得分:6)

“步骤”在这种情况下不是明确定义的术语 - 如pswaminathan points out,通常我们关心的不是精确的数值,而是广义上的数学行为:作为问题大小变大(在这种情况下,如果增加输入L的大小),执行时间是否保持不变?线性增长?平方?呈指数?

明确计算步骤可以成为分析的一部分 - 它可以是一种直观处理算法的好方法。但是,我们没有一致的方法来确定什么是“步骤”,什么不是。您可能正在查看代码行 - 但在Python中,例如,列表推导可以在一行中表达一个冗长,复杂的循环。或者你可以计算CPU指令,但是在一个更高级别的语言中,充满了绝对困难的抽象。因此,您选择一个启发式 - 在您的示例中使用简单的代码,“每行执行一行代码就是一个步骤”是一个不错的规则。在这种情况下,你肯定会计算打印报表。如果你想进一步深入,可以将字节码看作tobias_k suggests,以了解Python语法背后的指令。

但没有单一的商定规则。你提到它是为了做作业;在这种情况下,只有您的教师知道他们希望您使用什么定义。也就是说,对你的问题的简单回答很可能是“是的,印刷语句很重要。”

答案 1 :(得分:4)

如果你的任务是计算确切的步数,那么是的,print将算作一个步骤。但请注意,您的第二个print至少需要三步:列表访问,添加和打印。

事实上,print(以及其他“原子”语句)实际上可能值得许多“步骤”,具体取决于您如何解释步骤,例如CPU周期等。这对您的任务来说可能有点过分,但要准确,可能值得查看生成的字节代码。试试这个:

import dis
print dis.dis(function)

这将为您提供函数中或多或少原子步骤的完整列表,例如,加载函数,将参数传递给该函数,从堆栈中弹出元素等。据此,即使您的第一个{ {1}}值得三个步骤(在Python 2.6中):

print

如何解释这个:第一个数字(2 0 LOAD_CONST 1 ('Hello') 3 PRINT_ITEM 4 PRINT_NEWLINE )是行号(即,以下所有指令仅适用于该行);中心数字(2)是跳转标签(例如,if-statements和循环使用),后跟实际指令(0);右列包含这些指令的参数(LOAD_CONST)。有关详细信息,请参阅this answer