Статическая память в python: создают ли циклы новые экземпляры переменных в памяти? - PullRequest
11 голосов
/ 22 июля 2010

Я запускаю скрипты Python, которые делают несколько вызовов некоторых функций, например, F1 (x) и F2 (x), которые выглядят примерно так:

x = LoadData()

for j in range(N):
    y = F1(x[j])
    z[j] = F2(y)

    del y

SaveData(z)

Производительность намного выше, если я сохраню строку «del y». Но я не понимаю, почему это так. Если я не использую «del y», то у меня быстро заканчивается ОЗУ, и мне приходится прибегать к виртуальной памяти, и все замедляется. Купите, если я использую «del y», то я неоднократно очищаю и перераспределяю память для y. То, что я хотел бы сделать, это у вас сидеть как статическая память, и повторно использовать память при каждом вызове F1 (x). Но из того, что я могу сказать, это не то, что происходит.

Кроме того, не уверен, что это уместно, но мои данные состоят из пустых массивов.

Ответы [ 3 ]

12 голосов
/ 22 июля 2010

Без del y вам может понадобиться вдвое больше памяти.Это связано с тем, что для каждого прохода в цикле y привязывается к предыдущему значению F1, а вычисляется следующее.

, как только F1 возвращает y, возвращается к этому новому значению, истарый F1 результат может быть освобожден.

Это будет означать, что объект, возвращаемый F1, занимает довольно много памяти

Развертывание цикла для первой пары итераций будет выглядетьЭто

y = F1(x[0])   # F1(x[0]) is calculated, then y is bound to it
z[j] = F2(y)
y = F1(x[1])   # y is still bound to F1(x[0]) while F1(x[1]) is computed
               # The memory for F1(X[0]) is finally freed when y is rebound
z[j] = F2(y)

с использованием del y является хорошим решением, если это то, что происходит в вашем случае.

2 голосов
/ 22 июля 2010

то, что вы на самом деле хотите, это то, что странно делать в python - вы хотите выделить область памяти для y и передать указатель на эту область на F1(), чтобы он мог использовать эту область для созданияследующее значение y.это позволит избежать того, что F1() сделает свое собственное распределение для нового значения y, ссылка на который затем записывается в вашу собственную переменную y (которая на самом деле не является значением того, что F1() вычислено, а является ссылкой наэто)

Уже есть вопрос о передаче по ссылке в python: Как передать переменную по ссылке?

0 голосов
/ 22 июля 2010

Для очень больших значений N используйте xrange вместо range для сохранения памяти.Также вы можете вкладывать функции, но я не знаю, поможет ли это вам.: \

x = LoadData()

for j in xrange(N):
    z[j] = F2(F1(x[j]))

SaveData(z)

Может быть, F1 и F2 делают ненужные копии объектов, лучший способ был бы на месте, что-то вроде:

x = LoadData()
for item in x:
    item.F1()
    item.F2()
SaveData(x)

Извините, если ответ не поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...