在python中将变量设置为"None"是否更节省内存? [英] Is it more memory-efficient to set variables to `None` in python?

查看:793
本文介绍了在python中将变量设置为"None"是否更节省内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简单的问题,但是由于我没有找到任何答案,因此我认为答案将是负面的.但是,要确定,我要问:

在函数中使用完变量后,将变量设置为None是否会使python代码更有效?

举个例子:

def foo(fname):
    temp_1, temp_2 = load_file_data(fname)

    # do some processing on temp_1, temp_2

    temp_1 = None
    temp_2 = None

    # continue with the rest of the function

如果我们在函数末尾执行此操作,答案是否会更改(因为我认为python本身会在那时执行此操作)?

解决方案

这取决于您所说的更有效".

将变量设置为None(假设它们是对其值的唯一引用),将使垃圾收集器可以收集它们.在CPython(使用引用计数作为垃圾收集器)中,它甚至会立即这样做.

但是,另一方面,您还向该函数添加了更多的字节码,这些字节码必须由解释器执行,这会使代码对象更难保存在缓存中,依此类推.

请记住,释放内存几乎从不意味着实际上将内存释放给操作系统.大多数Python实现都有多个级别的空闲列表,并且通常位于类似malloc的顶部.因此,如果您要分配足够的额外内存来增加峰值内存大小,则空闲列表上有很多东西可能会阻止这种情况;如果您已经达到顶峰,则释放价值不太可能有任何不同. (这是假设峰值内存使用量对您的应用很重要-仅仅是因为到目前为止,最容易衡量的事情并不意味着它与每个问题都最相关.)

在几乎所有现实生活的代码中,这两种方法都不太可能产生任何变化.如果是这样,您将需要进行测试,并了解诸如内存压力和缓存局部性之类的因素如何影响您的应用程序.您可能会使代码变得更好,可能会变得更糟(至少假设并不是您唯一关心优化的事情是某些特定的内存测量),最有可能的是您没有效果,但会使其更长,因此效果更小可读的.这是过早的优化是万恶之源"这一格言的完美示例.


如果我们在函数末尾执行此操作,答案是否会更改(因为我认为python本身会在那时执行此操作)?

您是对的,当函数返回时,Python将释放局部变量.因此,是的,在那种情况下,您仍然会得到几乎所有的否定词,而几乎没有肯定的词,这很可能会改变答案.


但是,除了所有这些警告之外,在某些情况下这可能会改善某些情况.*因此,如果您对应用程序进行了配置,并发现将其保留太长时间会造成真正的问题,则一定要解决此问题. !

不过,请注意,del temp_1将具有与您正在寻找的效果相同的效果,并且在您的操作及其原因方面更加明确.而且在大多数情况下,最好将代码重构为较小的函数,以便temp_1和朋友在您自然地完成对它们的使用后就超出范围,而无需进行任何额外的工作.

*例如,假设该函数的其余部分只是前半部分的精确副本,带有三个新值.在空闲列表顶部拥有一组完美的候选者可能比必须更深入地搜索空闲列表要好,并且绝对比必须分配更多的内存并可能触发交换更好.

It is a simple question, but since I didn't find any answers for it, I assume the answer would be negative. However, to make sure, I'm asking it:

Does it make the python code more efficient to set the variables to None after we're done with them in a function?

So as an example:

def foo(fname):
    temp_1, temp_2 = load_file_data(fname)

    # do some processing on temp_1, temp_2

    temp_1 = None
    temp_2 = None

    # continue with the rest of the function

Does the answer change if we do this at the end of the function (since I assume python itself would do it at that point)?

解决方案

It depends on what you mean by "more efficient".

Setting the variables to None, assuming they're the only references to their values, will allow the garbage collector to collect them. And in CPython (which uses ref counting for its garbage collector), it will even do so right away.

But on the other hand, you're also adding more bytecodes to the function that have to be executed by the interpreter, and that make the code object harder to keep in cache, and so on.

And keep in mind that freeing up memory almost never means actually freeing memory to the OS. Most Python implementations have multiple levels of free lists, and it usually sits on top of something like malloc that does as well. So, if you were about to allocate enough additional memory to increase your peak memory size, having a lot of stuff on the free list may prevent that; if you've already hit your peak, releasing values is unlikely to make any difference. (And that's assuming peak memory usage is what matters to your app—just because it's by far the easiest thing to measure doesn't mean it's what's most relevant to every problem.)

In almost all real-life code, this is unlikely to make any difference either way. If it does, you'll need to test, and to understand how things like memory pressure and cache locality are affecting your application. You may be making your code better, you may be making it worse (at least assuming that some particular memory measurement is not the only thing you care about optimizing), most likely you're having no effect but to make it longer and therefore less readable. This is a perfect example of the maxim "premature optimization is the root of all evil".


Does the answer change if we do this at the end of the function (since I assume python itself would do it at that point)?

You're right that Python frees local variables when the function returns. So yes, in that case, you're still getting almost all of the negatives with almost none of the positives, which probably changes the answer.


But, all those caveats aside, there are cases where this could improve things.* So, if you've profiled your app and discovered that holding onto that memory too long is causing a real problem, by all means, fix it!

Still, note that del temp_1 will have the same effect you're looking for, and it's a lot more explicit in what you're doing and why. And in most cases, it would probably be better to refactor your code into smaller functions, so that temp_1 and friends go out of scope as soon as you're done with them naturally, without the need for any extra work.

* For example, imagine that the rest of the function is just an exact copy of the first half, with three new values. Having a perfect set of candidates at the top of the free lists is probably better than having to search the free lists more deeply—and definitely better than having to allocate more memory and possibly trigger swapping…

这篇关于在python中将变量设置为"None"是否更节省内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆