2015-01-16 3 views
1

Я использовал Python некоторое время и время от времени сталкиваюсь с проблемой взрыва памяти. Я искал для некоторых источников, чтобы решить мой вопрос, такие как Memory profiling embedded python и https://mflerackers.wordpress.com/2012/04/12/fixing-and-avoiding-memory-leaks-in-python/ и https://docs.python.org/2/reference/datamodel.html#object.del Однако ни один из них не работает для меня.Взрыв памяти Python со встроенными функциями

Моя текущая проблема - взрыв памяти при использовании встроенных функций. Следующие коды прекрасно работает:

class A: 
    def fa: 
    some operations 
    get dictionary1 
    combine dictionary1 to get string1 
    dictionary1 = None 
    return *string1* 

    def fb: 
    for i in range(0, j): 
     call self.fa 
     get dictionary2 by processing *string1* 
     # dictionary1 and dictionary2 are basically the same. 
     update *dictionary3* by processing dictionary2 
     dictionary2 = None 
    return *dictionary3* 

class B: 
    def ga: 
    for n in range(0, m): 
     call A.fb # as one argument is updated dynamically, I have to call it within the loop 
     processes *dictoinary3* 
    return something 

Проблема вызывает, когда я заметил, что мне не нужно сочетать dictionary1 к string1, я могу непосредственно передать dictionary1 в A.fb. Я реализовал его таким образом, тогда программа становится чрезвычайно медленной, и использование памяти взрывается более чем в 10 раз. Я проверил, что оба метода вернули правильный результат.

Может кто-нибудь предположить, почему такая небольшая модификация приведет к столь большой разнице?

Ранее я также заметил это, когда я выравнивал узлы в дереве с несколькими источниками (с 100 000 + узлами). Если я начну выравнивать исходный узел (который может иметь наибольшую высоту), использование памяти в 100 раз хуже, чем у исходного узла, который может иметь наименьшую высоту. Пока время выравнивания примерно одинаковое.

Это сбило меня с толку надолго. Огромное спасибо заранее!

Если кому-то интересно, я могу выслать вам исходный код для более четкого объяснения.

ответ

0

Тот факт, что вы решаете ту же проблему, не должен подразумевать ничего об эффективности решения. Та же проблема может быть заявлена ​​при сортировке массивов: вы можете использовать bubble-sort O(n^2) или merge-sort O(nlogn), или, если вы можете применить некоторые ограничения, вы можете использовать алгоритм сортировки без сравнения, такой как radix или bucket-sort, которые имеют линейное время выполнения ,

Начиная с пересечения с различными узлами будут генерироваться различные способы прохождения графика - некоторые из них могут быть неэффективными (повторяя узлы больше раз).

Что касается «комбинировать словарь1 с строкой1» - это может быть очень дорогостоящая операция, и поскольку эта функция называется рекурсивно (много раз), производительность может быть значительно хуже. Но это всего лишь образованная догадка, на которую нельзя ответить, не имея более подробной информации о сложности операций, выполняемых в этих функциях.

+0

Я полностью согласен с вами на основании моих образованных знаний о структуре данных и алгоритмах. Я не понимаю, что, устраняя процессы объединения, а затем отсоединения, я получу улучшения либо в процессорном времени, либо в использовании памяти, однако оба они становятся хуже ... – user186927

+0

Мы можем предположить - но это не будет продуктивный. Лучше попробуйте использовать профилировщик, чтобы понять разницу в производительности. – alfasin

+0

Привет, альфасин, я выяснил причину. Наконец, это связано с тем, что после изменения реализации некоторые форматы данных не являются строго одинаковыми. Программа проводила много времени, чтобы отличить их. Спасибо, что напомнили мне использовать профилировщик! – user186927

Смежные вопросы