Python - сборка мусора очень медленная, не может отключить gc - PullRequest
0 голосов
/ 18 июня 2019

Я занимаюсь разработкой программы, которая использует pandas фреймы данных и большие словари. Кадр данных считывается из CSV, который составляет ок. 700MB.

Я использую Python 3.7.3 в Windows

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

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

Я попытался профилировать свой код с помощью CProfile и обнаружил, что garbage-collector - это функция, которая занимает около 90% времени выполнения.

Я видел похожие проблемы, решаемые путем вызова gc.disable(), но это ничего не сделало для меня.

Странно (я понятия не имею, нормально ли это), но если я print(len(gc.get_objects())) в качестве первой строки кода, я получаю 51053, что выглядит много, учитывая, что ни одна функция еще не была вызвана.

Моя CProfile попытка: (на небольшой части CSV, поскольку для завершения попытки на полной CSV потребуется несколько часов)

cProfile.run('get_pfs_errors("Logs/L5/L5_2000.csv")', 'restats.txt')


import pstats
from pstats import SortKey
p = pstats.Stats('restats.txt')
p.sort_stats(SortKey.CUMULATIVE).print_stats(10)
p.sort_stats(SortKey.TIME).print_stats(10)

Вот статистика из CProfile:

Tue Jun 18 15:40:19 2019    restats.txt

         1719320 function calls (1459451 primitive calls) in 7.569 seconds

   Ordered by: cumulative time
   List reduced from 819 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    7.569    7.569 {built-in method builtins.exec}
        1    0.001    0.001    7.569    7.569 <string>:1(<module>)
        1    0.000    0.000    7.568    7.568 C:/Users/BC744818/Documents/OPTISS_L1_5/test_profile.py:6(get_pfs_errors)
        1    0.006    0.006    7.503    7.503 C:\Users\BC744818\Documents\OPTISS_L1_5\utils\compute_pfs_rules.py:416(compute_pfs_rules)
        1    0.197    0.197    7.498    7.498 C:\Users\BC744818\Documents\OPTISS_L1_5\utils\compute_pfs_rules.py:323(test_logs)
      264    0.001    0.000    6.532    0.025 C:\Users\BC744818\Documents\OPTISS_L1_5\venv\lib\site-packages\pandas\core\series.py:982(__setitem__)
      529    0.010    0.000    6.158    0.012 C:\Users\BC744818\Documents\OPTISS_L1_5\venv\lib\site-packages\pandas\core\generic.py:3205(_check_setitem_copy)
      528    6.125    0.012    6.125    0.012 {built-in method gc.collect}
      264    0.004    0.000    3.430    0.013 C:\Users\BC744818\Documents\OPTISS_L1_5\venv\lib\site-packages\pandas\core\series.py:985(setitem)
      264    0.004    0.000    3.413    0.013 C:\Users\BC744818\Documents\OPTISS_L1_5\venv\lib\site-packages\pandas\core\indexing.py:183(__setitem__)


Tue Jun 18 15:40:19 2019    restats.txt

         1719320 function calls (1459451 primitive calls) in 7.569 seconds

   Ordered by: internal time
   List reduced from 819 to 10 due to restriction <10>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      528    6.125    0.012    6.125    0.012 {built-in method gc.collect}
      264    0.405    0.002    0.405    0.002 {built-in method gc.get_objects}
        1    0.197    0.197    7.498    7.498 C:\Users\BC744818\Documents\OPTISS_L1_5\utils\compute_pfs_rules.py:323(test_logs)
 71280/33    0.048    0.000    0.091    0.003 C:\Users\BC744818\AppData\Local\Programs\Python\Python37\lib\copy.py:132(deepcopy)
   159671    0.033    0.000    0.056    0.000 {built-in method builtins.isinstance}
      289    0.026    0.000    0.026    0.000 {built-in method nt.stat}
167191/83791    0.024    0.000    0.040    0.000 C:\Users\BC744818\AppData\Local\Programs\Python\Python37\lib\json\encoder.py:333(_iterencode_dict)
  8118/33    0.019    0.000    0.090    0.003 C:\Users\BC744818\AppData\Local\Programs\Python\Python37\lib\copy.py:236(_deepcopy_dict)
167263/83794    0.017    0.000    0.048    0.000 C:\Users\BC744818\AppData\Local\Programs\Python\Python37\lib\json\encoder.py:277(_iterencode_list)
 1067/800    0.017    0.000    0.111    0.000 C:\Users\BC744818\Documents\OPTISS_L1_5\venv\lib\site-packages\pandas\core\indexes\base.py:253(__new__)

1 Ответ

0 голосов
/ 19 июня 2019

Спасибо @ user9993950, я решил это благодаря тебе.

Когда я тестировал эту программу, у меня было SettingWithCopyWarning, но я хотел зафиксировать скорость программы перед исправлением этого предупреждения.

Но так получилось, что, исправив предупреждение, я также значительно увеличил скорость программы, и gc больше не занимал все время работы

Я не знаю, чтовызвал это, хотя, если кто-то знает и хочет поделиться знаниями, пожалуйста, сделайте.

...