关于优化:如何减少Python脚本内存使用

How To Reduce Python Script Memory Usage

我有一个非常大的python脚本,200K,我想尽可能少使用内存。 它看起来像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# a lot of data structures
r = [34, 78, 43, 12, 99]

# a lot of functions that I use all the time
def func1(word):
    return len(word) + 2

# a lot of functions that I rarely use
def func1(word):
    return len(word) + 2


# my main loop
while 1:
   # lots of code
   # calls functions

如果我把我很少使用的函数放在模块中,并且只在必要时动态导入它们,我就无法访问数据。 就我而言,这就是我的意思。

我是python的新手。

任何人都可以把我放在正确的道路上吗? 如何打破这个大脚本,以便它使用更少的内存? 是否值得将很少使用的代码放在模块中,只在需要时调用它们?


Organazing:

您的python脚本似乎确实很大,也许您应该考虑首先重新组织代码,分成几个模块或包。它可能会使代码分析和优化任务变得更容易。

你可能想看看那里:

  • Python Project Howto
  • Python包
  • SO:组织我的Python项目

可能:

  • SO:Python:什么是常见的标题格式?
  • 你如何组织Python模块?
  • Hitchiker的包装指南

优化:

有很多事情可以用来优化你的代码......

例如,关于您的数据结构......如果您大量使用列表或列表推导,您可以尝试找出您真正需要列表的位置,以及它们可能被替换为非可变数据结构(如元组或通过"volatile"对象,"懒惰"容器,如生成器表达式。

看到:

  • 那么:元组比Python中的列表更有效吗?
  • SO:生成器表达式与列表理解
  • PEP 255 - 简单生成器和PEP 289 - 生成器表达式

在这些页面上,您可以找到一些有用的信息和提示:

  • http://wiki.python.org/moin/PythonSpeed
  • http://wiki.python.org/moin/PythonSpeed/PerformanceTips
  • http://wiki.python.org/moin/TimeComplexity
  • http://scipy.org/PerformancePython

此外,你应该研究你做事的方式,并想知道是否有办法减少贪婪,这是一种在Python中更好的方法(你会发现pythonic标签中的一些提示)......特别是在Python中是真的,因为在Python中,通常有一种"明显"的方式(并且只有一种)来做比其他方式更好的方法(参见Python的Zen),据说它是pythonic。它与你的代码的形状没有特别的关系,而且最重要的是与表演有关。与许多语言不同,Python提出了应该有很多方法可以做任何事情的方法,但Python更喜欢只关注最好的方法。很明显,有很多方法可以做某事,但通常情况下,一个方法确实更好。

现在,您还应该验证您是否使用最佳方法来执行操作,因为pythonicality不会为您安排算法。

但最后,它很大程度上取决于你的代码,如果没有看到它就很难回答。

并且,请务必考虑eumiro和Amr的评论。


这段视频可能会给你一些好主意:http://pyvideo.org/video/451/pycon-2011---quot-dude--where--39-s-my-ram--quot-


关于生成器表达式和使用模块的建议很好。过早优化会导致问题,但在开始编写代码之前,您应该花几分钟时间考虑一下您的设计。特别是如果该代码是要重用的话。

顺便提一下,你提到你在脚本的顶部定义了很多数据结构,这意味着它们在开始时都被加载到内存中。如果这是一个非常大的数据集,请考虑将特定数据集移动到单独的文件,并仅在需要时加载它们。 (使用csv模块或numpy.loadtxt()等)

与使用较少的内存分开,还要研究更有效地使用内存的方法。例如,对于大型数值数据集,numpy数组是一种存储信息的方式,可以在计算中提供更好的性能。在http://wiki.python.org/moin/PythonSpeed/PerformanceTips上有一些稍微过时的建议


移动函数不会改变您的内存使用情况。只要导入其他模块,它就会定义模块中的所有功能。但是功能不占用太多内存。它们是非常重复的,也许你可以通过重构函数来减少代码吗?

@ eumiro的问题是对的:你确定你的脚本使用了太多内存吗?它使用了多少内存,为什么它太多了?


如果您正在利用OOP并拥有一些对象,请说:

1
2
3
4
5
class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

您可以通过输入来使对象占用更少的内存:

1
__slots__ = ("lorem","ipsum")

就在__init__函数之前,如图所示:

1
2
3
4
5
class foo:
    def __init__(self, lorem, ipsum):
        self.lorem = lorem
        self.ipsum = ipsum
    # some happy little methods

当然,"过早优化是万恶之源"。 还要在添加之前和之后配置mem使用情况,看看它是否真的有效。 小心破坏代码(shcokingly),理解这可能最终无法正常工作。