Является ли более эффективной память для установки переменных в "None" в python?

Это простой вопрос, но поскольку я не нашел для него никаких ответов, я предполагаю, что ответ будет отрицательным. Однако, чтобы убедиться, я спрашиваю:

Является ли код python более эффективным для установки переменных в None после того, как мы закончим с ними в функции?

Итак, в качестве примера:

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 будет делать это в этой точке)?

Ответ 1

Это зависит от того, что вы подразумеваете под "более эффективным".

Установка переменных в None, предполагая, что они являются единственными ссылками на их значения, позволит сборщику мусора собирать их. И в CPython (который использует ref counting для своего сборщика мусора), он даже сделает это сразу.

Но, с другой стороны, вы также добавляете больше байт-кодов к функции, которая должна быть выполнена интерпретатором, и это делает объект кода сложнее хранить в кеше и т.д.

И имейте в виду, что освобождение памяти почти никогда не означает фактическое освобождение памяти для ОС. Большинство реализаций на Python имеют несколько уровней бесплатных списков, и он обычно сидит поверх чего-то вроде malloc, что и делает. Итак, если вы собираетесь выделить достаточную дополнительную память для увеличения своего пикового объема памяти, наличие большого количества материала в свободном списке может помешать этому; если вы уже достигли пика, то высвобождение значений вряд ли имеет значение. (И то, что при использовании пиковой памяти важно для вашего приложения, просто потому, что на самом деле самое простое измерение - это не самое главное для каждой проблемы.)

Практически во всех реальных кодексах это вряд ли имеет какое-либо значение. Если это так, вам нужно протестировать и понять, как такие вещи, как давление памяти и местонахождение кеша, влияют на ваше приложение. Возможно, вы улучшаете свой код, возможно, вы ухудшаете его (по крайней мере, предполагая, что какое-то конкретное измерение памяти - это не единственное, что вам нужно для оптимизации), скорее всего, вы не имеете никакого эффекта, но чтобы сделать его дольше и, следовательно, меньше удобочитаемый. Это прекрасный пример максимы: "преждевременная оптимизация - это корень всего зла".


Изменяется ли ответ, если мы делаем это в конце функции (поскольку я предполагаю, что сам python будет делать это в этой точке)?

Вы правы, что Python освобождает локальные переменные при возврате функции. Так что да, в этом случае вы по-прежнему получаете почти все негативы практически без каких-либо положительных эффектов, что, вероятно, изменяет ответ.


Но, все эти оговорки в стороне, бывают случаи, когда это может улучшить ситуацию. * Итак, если вы профилировали свое приложение и обнаружили, что слишком долго удерживать эту память, это создает настоящую проблему, во что бы то ни стало, исправить ее

Тем не менее, обратите внимание, что del temp_1 будет иметь тот же эффект, который вы ищете, и он намного более ясен в том, что вы делаете и почему. И в большинстве случаев было бы лучше реорганизовать ваш код на более мелкие функции, так что temp_1 и друзья выходят за рамки, как только вы с ними справитесь, естественно, без необходимости в дополнительной работе.

* Например, представьте, что остальная часть функции представляет собой точную копию первой половины с тремя новыми значениями. Наличие идеального набора кандидатов в верхней части свободных списков, вероятно, лучше, чем поиск свободных списков более глубоко - и определенно лучше, чем необходимость выделять больше памяти и, возможно, инициировать свопинг...

Ответ 2

Я не согласен с тем, что это будет быстрее, если вы не столкнетесь с ситуацией, когда у вас заканчивается память.

В обычном приложении, как только переменные в вашей функции покинут область видимости, они будут помечены как более не используемые, освобожденные или другие, что делает конкретный интерпретатор python. Установка на None будет означать больше работы для python, поскольку это позволит освободить память, на которую указывает ваша переменная, но не сама переменная.

Кроме того, в общем случае python использует подсчет ссылок, а не сбор мусора, поэтому, когда счетчик ссылок падает до нуля, объект будет свободен.