Python的基本优化模式有什么用? (python -O)
Python有一个标志-O
,你可以执行解释器。 该选项将生成“优化”的字节码(写入.pyo文件),并给出两次,它会丢弃文档。 从Python的手册页:
-O打开基本的优化。 这将编译(字节码)文件的文件扩展名从.pyc更改为.pyo。 给定两次,导致docstrings被丢弃。
这个选项的两个主要特点,我看到它是:
-
剥离所有断言语句。 这为防止腐败的程序状态提供了防御速度。 但是,你不需要大量的声明来做出改变吗? 你有任何代码,这是值得的(和理智?)
-
去除所有文档。 在什么应用程序的内存使用如此重要,这是一个胜利? 为什么不把所有的东西都放到C语言模块中?
这个选项有什么用? 它有真实世界的价值吗?
在剥离断言语句方面:这是C世界的一个标准选项,许多人认为ASSERT的部分定义是它不能在生产代码中运行。 无论是否剥夺它们,都会影响到决定性的程度,而不是取决于有多less断言,而不是这些断言所做的工作量。
def foo(x): assert x in huge_global_computation_to_check_all_possible_x_values() # ok, go ahead and use x...
当然,大多数断言不是这样的,但重要的是要记住,你可以做这样的事情。
至于剥离docstrings,它似乎从简单的时间古怪的保留,但我想有内存限制的环境,它可以有所作为。
-O
标志的另一个用法是将__debug__
内置variables的值设置为False
。
所以,基本上,你的代码可以有很多“debugging”path,如:
if __debug__: # output all your favourite debugging information # and then more
当在-O
下运行时,甚至不会将其作为字节码包含在.pyo
文件中; 一个穷人的C-ish #ifdef。
请记住, 只有当标志是-OO
时文档string才会被删除。
如果你在经常被调用的代码中(例如在内部循环中)声明,剥离它们肯定会有所作为。 极端例子:
$ 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]
在实际情况下,储蓄通常会less得多。
剥离文档可能会减less代码的大小,从而缩小您的工作集。
在很多情况下,性能影响可以忽略不计,但是像优化一样,唯一可以肯定的就是测量。
我从来没有遇到过使用-O
的好理由。 我一直认为它的主要目的是在将来的某个时候join一些有意义的优化。
你几乎已经知道了:它几乎没有任何东西。 除非你对内存造成严重伤害,否则几乎不会看到速度或内存的增加。
我想象一下-O
最重的用户是py2exe py2app和类似的。
我个人从来没有直接find-O
的用法。
但是,你不需要大量的声明来做出改变吗? 你有任何代码,这是值得的(和理智?)
作为一个例子,我有一段代码在图中的节点之间获取path。 我在函数的末尾有一个assert语句来检查path是否包含重复项:
assert not any(a == b for a, b in zip(path, path[1:]))
我喜欢这个简单的陈述在开发过程中给予的安心和清晰 。 在生产中,代码会处理一些大图,这一行可能会占用运行时间的66%。 与-O
运行因此提供了显着的加速。