Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。
在这篇文章中,我会介绍一些能在Python中帮助我们解决痛苦问题的工具,特别是当我们使用PyPy时的内存消耗问题。
为什么我们第一个关心这个问题呢?为什么我们不仅仅关心性能?这些问题的答案非常复杂,但我会总结出来。
PyPy是一个可选的Python解释器,它具有比CPython更大的优势:速度(通过它的JIT编译器),兼容性(几乎可以替代CPyton)和并发性(使用stackless和greenlets)。
PyPy有一个缺点,由于它的JIT和垃圾一样的回收站实现,所以它通常会比CPython使用更多的内存。然而在某些情况下,它能够比CPython消耗更少的内存。
接下来我们来看看如何测量你的程序使用了多少内存。
诊断内存的使用情况
memory_profiler
这是一个可以用于测量解释器运行一个负载时使用的内存量的库,名称为memory_profiler。它可以通过pip安装:
并且需要安装psutil依赖包:
这个工具的优点是会在Python脚本中一行行的显示内存的消耗。这有助于我们从脚本中找到可以重写的地方,但这种分析带来了一个缺点。你的代码将比一般的脚本运行慢10到20倍。
怎么使用它呢?你只需要将@profile()添加到你需要测试的函数中就可以了。
让我们看看它的运行吧!我们将使用我们之前文章中的素材脚本作为模型,稍微修改以删除统计部分。它可以在GitHub上查看。
https://github.com/apatrascu/hunting-python-performance/blob/master/02.primes-v1.py
开始测试,需要使用以下PyPy命令:
或者更简短,通过直接在脚本中导入memory_profiler:
执行这一行代码之后,我们将看到PyPy得到如下的结果:
我们可以看到这个脚本使用了24.371094MiB的RAM。让我们分析一下,我们看到其中大多数是在构建数组时使用,这个数组排除了偶数,保存了所有其他的数值。
我们可以通过调用range函数来改善这一点,其使用一个增量参数。
如果再次测试,我们会看到如下结果:
不错,现在我们的内存消耗降到了22.75MiB。消耗可以通过使用列表解析(list comprehension)再次降低。
再次测试:
我们脚本的最终版本仅消耗了22.451875MiB。这几乎比第一个版本减少了10%。
英文原文:https://pythonfiles.wordpress.com/2017/05/18/hunting-python-performance-part-2/
译者:南北丶