Python的基本优化模式有什么用?(python -O)
Python 有一个选项 -O
,可以用来启动解释器。这个选项会生成“优化过”的字节码(保存在 .pyo 文件中),如果你输入两次这个选项,它会去掉文档字符串。根据 Python 的手册页面:
-O 开启基本优化。这会把编译后的(字节码)文件的扩展名从 .pyc 改为 .pyo。如果输入两次,会去掉文档字符串。
我认为这个选项有两个主要功能:
去掉所有的断言语句。这是为了提高速度,牺牲了一些程序状态的安全性。但是,难道不需要很多断言语句才能让这个优化有意义吗?你有没有什么代码是值得这样做的(而且是合理的)?
去掉所有的文档字符串。在什么情况下,内存使用这么重要,以至于这样做是有好处的?为什么不把所有东西都写成 C 语言的模块呢?
这个选项有什么用呢?它在现实中真的有价值吗?
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]
在实际情况中,节省的空间通常会少得多。
去掉文档字符串可能会减少你代码的大小,从而减小你需要处理的数据量。
在很多情况下,性能的影响可能微乎其微,但就像优化一样,唯一能确定的方法就是进行测量。
另一个使用 -O
标志的地方是,它会把内置变量 __debug__
的值设置为 False
。
简单来说,你的代码可以有很多“调试”路径,比如:
if __debug__:
# output all your favourite debugging information
# and then more
在使用 -O
运行时,这些路径甚至不会被包含在 .pyo
文件的字节码中;这就像是一个简单的 C 语言中的 #ifdef 功能。
记住,只有在使用 -OO
标志时,文档字符串才会被去掉。
关于去掉断言语句:在C语言的世界里,这是一个常见的做法,很多人认为断言(ASSERT)的定义之一就是它在生产环境中不会被执行。去掉这些断言是否有影响,主要取决于断言的数量和它们所做的工作量,而不是单纯的数量:
def foo(x):
assert x in huge_global_computation_to_check_all_possible_x_values()
# ok, go ahead and use x...
当然,大多数断言并不是这样,但记住你可以做这样的事情是很重要的。
至于去掉文档字符串,这似乎是从一个简单时代遗留下来的做法,虽然我想在一些内存有限的环境中,这可能会有一些影响。