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运行因此提供了显着的加速。