Python的基本优化模式有什么用? (python -O)

时间:2009-11-07 13:51:35

标签: python optimization assert bytecode

Python有一个标志-O,你可以用它来执行解释器。该选项将生成“优化”字节码(写入.pyo文件),并给出两次,它将丢弃文档字符串。从Python的手册页:

  

-O启用基本优化。这会更改文件扩展名   对于从.pyc到.pyo的已编译(字节码)文件。两次,   导致文档字符串被丢弃。

这个选项是我看到的两个主要功能:

  • 删除所有断言语句。为了速度,这可以防止腐败的程序状态。但是,你不需要大量的断言声明才能有所作为吗?你有任何值得的代码(并且理智吗?)

  • 删除所有文档字符串。什么应用程序的内存使用如此关键,这是一个胜利?为什么不将所有内容都推入用C语言编写的模块?

这个选项有什么用? 它有真实世界的价值吗?

7 个答案:

答案 0 :(得分:44)

-O标志的另一个用途是__debug__内置变量的值设置为False

所以,基本上,你的代码可以有很多“调试”路径,如:

if __debug__:
     # output all your favourite debugging information
     # and then more

,在-O下运行时,甚至不会作为字节码包含在.pyo文件中;一个穷人的C-ish #ifdef。

请注意,当标记为-OO时,文档字符串只会被删除

答案 1 :(得分:30)

剥离断言语句:这是C世界中的标准选项,许多人认为ASSERT的部分定义是它不在生产代码中运行。是否剥离它们会产生影响取决于有多少断言取决于断言所做的工作量:

def foo(x):
    assert x in huge_global_computation_to_check_all_possible_x_values()
    # ok, go ahead and use x...

当然,大多数断言都不是那样,但重要的是要记住你可以做那样的事情。

至于剥离文档字符串,它似乎从一个更简单的时间看起来像一个古怪的保留,但我想有一些内存受限的环境,它可以产生影响。

答案 2 :(得分:7)

如果你在频繁调用的代码中有断言(例如在内循环中),剥离它们肯定会产生影响。极端的例子:

$ python    -c 'import timeit;print timeit.repeat("assert True")'
[0.088717937469482422, 0.088625192642211914, 0.088654994964599609]
$ python -O -c 'import timeit;print timeit.repeat("assert True")'
[0.029736995697021484, 0.029587030410766602, 0.029623985290527344]

在实际情况中,节省的费用通常会少得多。

剥离文档字符串可能会减少代码的大小,从而减少工作集。

在许多情况下,性能影响可以忽略不计,但与优化一样,唯一可以确定的方法是衡量。

答案 3 :(得分:7)

我从未遇到过使用-O的充分理由。我一直认为它的主要目的是在未来的某些时候增加一些有意义的优化。

答案 4 :(得分:5)

我认为-O中最重的用户是py2exe py2app并且类似。

我个人从未直接使用-O

答案 5 :(得分:4)

你几乎已经弄明白了:它几乎什么都没做。你几乎永远不会看到速度或内存增益,除非你对RAM造成严重伤害。

答案 6 :(得分:2)

  

但是你不需要大量的断言声明才能有所作为吗?你有任何值得的代码(并且理智吗?)

作为一个例子,我有一段代码可以获取图形中节点之间的路径。我在函数末尾有一个断言语句,用于检查路径是否包含重复项:

assert not any(a == b for a, b in zip(path, path[1:]))

我喜欢这个简单语句在开发过程中提供的peace of mind and clarity。在生产中,代码处理一些大图,这一行可能占用运行时间的66%。因此,使用-O运行会显着加快速度。