2013-03-12 3 views
4

Я писал длинный скрипт, который изредка строит большие диктофоны и/или списки, и мне было интересно, можно ли повысить производительность, удалив их с помощью del, когда я закончу использовать их. Или это нормальная практика оставить эти объекты висящими вокруг заботиться о сборе мусора? Какая здесь самая лучшая практика? Благодарю.Периодически удалять длинные дикты/списки в хорошей практике Python?

+0

Если я правильно помню, удаление значений из списка/dict просто выведет значения в GC и перестанет ссылаться на них в списке dict, так что у вас все еще будет вся память, которую будет обрабатывать GC, она просто сломана на мелкие кусочки. Возможно, я ошибаюсь, я не провел подробного изучения python GC – Aren

+1

В CPython, если они выходят за пределы области действия, они собираются (ссылки на круговые ссылки). Из вашего вопроса также не ясно, имеете ли вы в виду удаление членов списка или целых списков ... –

ответ

7

del не является эквивалентом бесплатного (3). Это не заставляет Python освобождать память. Возможно, это не освободит память. Вы не должны полностью связывать его с использованием памяти.

Единственная вещь del. Is is a a имя из его сферы. (Или удалить элемент из коллекции, или удалить атрибут Но я предполагаю, что это не то, что вы говорите здесь.).

Фактически, это:

del foo 

равносильна этому:

del LOCAL_SCOPE['foo'] 

Так что это не освобождает любую память:

massive_list = list(range(1000000)) 
same_massive_list = massive_list 
del massive_list 

... потому что все это делает удалить имяmassive_list. У базового объекта все еще есть другое имя: same_massive_list, поэтому оно не исчезает. del не является секретным приложением для управления памятью Python; это всего лишь один из нескольких способов: ask Python to invoke управление памятью.

(Кстати, CPython является refcounted + цикл собранными, а не сборщиком мусора. Объекты сразу освобожден, как только последняя ссылка на них исчезает. Мусор не лежит в ожидании быть очищены. Из Конечно, и другие варианты реализации делают разные вещи, PyPy, например, мусора)

Теперь, если имя, которое вы используете это только имя для списка/Dict/что угодно, то del, безусловно, вызывает его RefCount. чтобы упасть до нуля, поэтому он будет освобожден. Но, так как семантика del действительно об удалении имена, я бы не использовал его в этом случае. Я бы просто допустил, чтобы переменная выпала из сферы действия (если она была практической) или переназначила имя в пустой список, или None, или что-то, что имеет смысл для вашей программы. Вы даже можете очистить список в месте, которое будет работать, даже если есть несколько названий одного и того же списка:

foo = list(range(1000000)) 
bar = foo 
foo[:] = [] 
# Both `bar` and `foo` still refer to the original list, but now it's empty 

Вы можете сделать то же самое в Словаре с d.clear().

Единственное место, где я хотел бы использовать del по имени в классе или модуле сферы, где временно необходимо некоторое значение, но помощник действительно очень не хотят подвергать его как часть API. Это действительно редко, но это единственный случай, с которым я столкнулся, где я действительно хочу семантику «удалить это имя».

+0

Как этот ответ, особенно бит об опорожнении контейнеров. – kindall

+0

Я нахожу 'del foo [:]' более кратким. – nneonneo

+0

Мне нравится резервировать 'del' только для удаления имен. списки и dicts имеют '.pop', а списки имеют синтаксис среза, поэтому нет необходимости в специальной конструкции; Удаление переменных может быть выполнено (ish) с помощью 'del'. это также позволяет избежать проблемы с проверкой: когда вы видите 'del super_duper_long_name [2]', вы не можете фактически сказать, какой вкус 'del', пока вы не прочтете до конца строки. – Eevee

1

del обычно не требуется.

В CPython объекты исчезают, когда нет ссылок на них. del удаляет только одну ссылку на объект; если есть еще другие ссылки на объект, он останется вокруг, и del действительно ничего не сделал, чтобы улучшить ситуацию с памятью.

С другой стороны, просто переназначение переменной в другой объект (скажем, создание нового пустого списка в верхней части петли) будет также в конечном итоге с одним меньше ссылкой на объект, неявно делает то же самое, как del. Если в этот момент нет других ссылок на объект, он будет немедленно освобожден.

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

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

В IronPyothon (который работает на .NET CLR) или Jython (который работает на JVM) оптимальные стратегии управления памятью могут отличаться, поскольку используется сборщик мусора базовой виртуальной машины.

0

Одним из преимуществ Python (по сравнению с такими языками, как C) является то, что вам вообще не нужно беспокоиться о деталях управления памятью, и вы можете сосредоточиться на цели своей программы.

Так что я бы посоветовал не беспокоиться , если у вас нет оснований для этого (например, python ест всю вашу оперативную память).