2013-06-27 51 views
7

(这是一个后续Statistical profiler for PyPy优化PyPy

我跑PyPy下一些Python代码,并想优化它。

在Python中,我将使用statproflineprofiler来知道哪些确切的线条正在导致放缓并尝试解决它们。但在PyPy中,这两种工具并没有真正报告合理的结果,因为PyPy可能会优化掉一些行。我也不想使用cProfile,因为我发现很难提取报告功能的哪一部分是瓶颈。

有没有人有关于如何进行的一些提示?也许另一个在PyPy下很好地工作的profiler?一般来说,如何优化PyPy的Python代码?

回答

5

如果你了解PyPy架构的工作方式,你就会意识到,试图找出的代码各行是不是真的生产。你首先用一个用RPython编写的Python解释器开始,然后通过一个跟踪JIT来生成流图,然后转换这些图来优化RPython解释器。这意味着由正在被JIT处理的RPython解释器运行的Python代码的布局可能与实际运行的优化的汇编器具有非常不同的结构。此外,请记住,JIT始终在循环或函数上工作,因此逐行统计不太有意义。因此,我认为cProfile对您来说可能是一个很好的选择,因为它会让您了解优化的重点。一旦知道哪些功能是瓶颈,您可以针对那些较慢的功能进行优化,而不是尝试修复一行Python代码。

请记住,你这样做是PyPy比CPython的不同性能特点。总是尽量以尽可能简单的方式编写代码(这并不意味着尽可能少的行数)。还有其他一些启发式方法可以帮助您,例如使用专用列表,当您使用少量大多数恒定键时,使用对象覆盖字典,避免使用C Python API的C扩展等。

如果您真的,真的坚持试图在生产线一级进行优化。有几个选项。一个叫做JitViewer(https://bitbucket.org/pypy/jitviewer),它可以让你对JIT在你的代码中做什么有非常低的认识。例如,你甚至可以看到与Python循环对应的汇编指令。使用该工具,您可以真正了解PyPy将如何快速处理代码的某些部分,因为您现在可以做一些愚蠢的事情,如计算用于循环的汇编程序指令的数量等。

+0

你的建议是什么? –

+1

我的建议是只使用cProfile,因为PyPy的实际工作方式。我的第二个建议是使用JitViewer,如果你真的需要对代码的性能特征有一个低级的理解。 – jlund3

+1

在编译和优化实现解释器本身的RPython代码时,应用流程图转换*,而不是*您的Python代码。这些转换相当于C编译器应用于CPython解释器的C代码的转换,并且与最终用户的Python代码无关。 PyPy的JIT的确提出了你所讨论的问题,热循环可能会被JIT编译为多个不同的汇编代码块,这使得将性能映射回单个Python语句变得非常棘手。 – Ben