Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it more memory-efficient to set variables to `None` in python?

Tags:

python

memory

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)?

like image 757
oxtay Avatar asked Sep 25 '14 19:09

oxtay


People also ask

Does none take up memory Python?

It turns out that None consumes 16 bytes and that's actually too much for simply an empty value.

Is Python not memory efficient?

Python optimizes memory utilization by allocating the same object reference to a new variable if the object already exists with the same value. That is why python is called more memory efficient.

How much memory is allocated for a variable in Python?

Memory allocation for variables is completely independent of what type of object they refer to. Whether you assign x = [] , x = 5 , or x = SomeCrazyHugeThing() , the value doesn't affect the memory allocated for x .


1 Answers

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…

like image 103
abarnert Avatar answered Sep 21 '22 09:09

abarnert