【问题标题】:How does one use `dis.dis` to analyze performance?如何使用`dis.dis`来分析性能?
【发布时间】:2013-10-19 19:16:43
【问题描述】:

我正在尝试使用 python 的 dis 库来试验和了解性能。下面是我尝试的一个实验,有了结果。

import dis

def myfunc1(dictionary):
    t = tuple(dictionary.items())
    return t

def myfunc2(dictionary, func=tuple):
    t = func(dictionary.items())
    return t

>>> dis.dis(myfunc1)

  4           0 LOAD_GLOBAL              0 (tuple)
              3 LOAD_FAST                0 (dictionary)
              6 LOAD_ATTR                1 (items)
              9 CALL_FUNCTION            0
             12 CALL_FUNCTION            1
             15 STORE_FAST               1 (t)

  5          18 LOAD_FAST                1 (t)
             21 RETURN_VALUE 

>>> dis.dis(myfunc2)

  4           0 LOAD_FAST                1 (func)
              3 LOAD_FAST                0 (dictionary)
              6 LOAD_ATTR                0 (items)
              9 CALL_FUNCTION            0
             12 CALL_FUNCTION            1
             15 STORE_FAST               2 (t)

  5          18 LOAD_FAST                2 (t)
             21 RETURN_VALUE    

现在,我明白了……

  • 最左边的45 是行号
  • 中间一列是机器调用的操作码
  • 右边的列是对象(opargs?)

...但这一切在性能方面意味着什么?如果我试图决定使用哪个函数,我将如何使用dis 来比较两者?

提前致谢。

【问题讨论】:

  • 不要为此使用dis.dis。使用timeitdis 可用于比较不同代码示例之间的字节码差异,这可能会让您了解一个编程构造是否编译为比另一个复杂得多的字节码。对于真正的性能问题,您应该分析、测量执行时间。
  • 一般你不能。字节码的执行时间可能大不相同。例如,对 C 函数的调用是单个字节码,但可能需要数年才能执行,而在其他情况下,您有数十个字节码,但都需要几纳秒。要比较性能,请使用分析器。
  • 谢谢你们。我什至不知道现在是否需要“答案”。 :-)
  • 在这种特定情况下,由于在两个实例中被调用的东西是相同的(因此CALL_FUNCTION 时间无关紧要),我们可以说第二个函数执行得更快。字节码之间的唯一区别是myfunc2 使用LOAD_FAST,而1 使用LOAD_GLOBAL,因为正在加载的东西是2 中的函数参数。由于LOAD_FAST 非常快,因为它只加载函数对象的一个​​槽,而LOAD_GLOBAL 使用相当复杂的查找,2 将(非常稍微)更快。这也可以通过将 func 设为局部变量而不是参数来完成。
  • @l4mpi 我认为您的分析是 OP 正在寻找的答案。目前唯一可用的答案告诉 OP 不要使用dis 进行性能分析,这对初学者来说是一个很好的一般建议,但不是这个问题的好答案。您可能想重新发布您的评论作为答案。

标签: python performance python-2.7


【解决方案1】:

您(或至少是普通人)无法查看不同的汇编代码,并判断哪个更快。

尝试 IPython 中的 %%timeit 魔术函数。

它会自动运行这段代码几次,并给你一个客观的答案。

我最近发现 this blog post 教授如何在 Python 中测量这些东西。不仅是时间,还有内存使用。这篇文章的亮点(至少对我而言)是它教你实现 %lprun 魔法函数的时候。

使用它,您将能够逐行查看您的功能,并准确了解每个功能对花费的总时间的贡献。

我已经使用了几个星期了,非常棒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 2017-07-11
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    相关资源
    最近更新 更多