我有一个非常大的python脚本,200K,我想使用尽可能少的内存。 它看起来像:
# 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的新手。
谁能让我走上正确的道路? 如何分解此大型脚本以使其使用更少的内存? 是否值得将很少使用的代码放在模块中并仅在需要时调用它们?
组织:
你的python脚本看起来确实很大,也许你应该考虑先重新组织你的代码,把它分成几个模块或包。它可能会使代码分析和优化任务变得更容易。
你可能想看看那里:
- Python 项目操作方法
- 蟒蛇包
- SO:组织我的 Python 项目
并且可能:
- SO:Python:常见的标头格式是什么?
- 你如何组织Python模块?
- 希奇克包装指南
优化:
可以做很多事情来优化您的代码......
例如,关于您的数据结构...如果你大量使用列表或列表推导式,你可以尝试找出你真正需要列表的地方,以及它们可能被不可变的数据结构(如元组)或"易失性"对象、"惰性"容器(如生成器表达式)所取代。
看:
- SO:元组比 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的禅宗),这被称为pythonic。它与代码的形状没有特别的关系,但最重要的是,与性能有关。与许多语言不同,许多语言提倡应该有很多方法可以做任何事情,Python更喜欢只关注最好的方法。所以很明显,做某事有很多方法,但通常,一种确实更好。
现在,您还应该验证您是否正在使用最佳方法来做事,因为pythonity不会为您安排算法。
但最后,它因你的代码而异,如果没有看过它,很难回答。
并且,请务必考虑eumiro和Amr的评论。
关于生成器表达式和使用模块的建议很好。过早的优化会导致问题,但在坐下来编写代码之前,您应该始终花几分钟思考您的设计。特别是如果该代码是要重用的。
顺便提一下,您提到在脚本顶部定义了大量数据结构,这意味着它们在开始时都加载到内存中。如果这是一个非常大的数据集,请考虑将特定数据集移动到单独的文件,并仅在需要时加载它。(使用csv
模块,或numpy.loadtxt()
等)
除了使用更少的内存之外,还要研究更有效地使用内存的方法。例如,对于大型数值数据集,numpy 数组是一种存储信息的方法,可在计算中提供更好的性能。在 http://wiki.python.org/moin/PythonSpeed/PerformanceTips
移动函数不会改变您的内存使用情况。 导入其他模块后,它将定义模块中的所有函数。 但是函数不会占用太多内存。 它们是否非常重复,也许您可以通过重构函数来减少代码?
@eumiro的问题是对的:你确定你的脚本使用了太多内存吗? 它使用了多少内存,为什么它太多了?
如果您正在利用 OOP 并且有一些对象,请说:
class foo:
def __init__(self, lorem, ipsum):
self.lorem = lorem
self.ipsum = ipsum
# some happy little methods
您可以通过放入以下内容来使对象占用更少的内存:
__slots__ = ("lorem", "ipsum")
就在__init__
函数之前,如下所示:
class foo:
def __init__(self, lorem, ipsum):
self.lorem = lorem
self.ipsum = ipsum
# some happy little methods
当然,"过早优化是万恶之源"。还要分析添加前后的mem使用情况,以查看它是否真的做了什么。当心破坏代码(笨拙地),并理解这可能最终不起作用。