У меня есть проблема, чтобы разобрать 1000 текстовых файлов (около 3000 строк в каждом файле размером ~ 400 КБ) в папке. Я прочитал их, используя readlines,
for filename in os.listdir (input_dir) :
if filename.endswith(".gz"):
f = gzip.open(file, 'rb')
else:
f = open(file, 'rb')
file_content = f.readlines()
f.close()
len_file = len(file_content)
while i < len_file:
line = file_content[i].split(delimiter)
... my logic ...
i += 1
Это работает отлично для образца с моих входов (50 100 файлов). Когда я запускал весь ввод более чем 5K файлов, время было нигде близко к линейному приращению. Я планировал провести анализ производительности и проанализировать Cprofile. Время, затрачиваемое на большее количество файлов, экспоненциально возрастает с увеличением ставок при входе в файлы 7K.
Вот кумулятивное время, затраченное на чтение строк, сначала → 354 файла (образец со входа) и второй → 7473 файла (всего ввода)
ncalls tottime percall cumtime percall filename:lineno(function)
354 0.192 0.001 **0.192** 0.001 {method 'readlines' of 'file' objects}
7473 1329.380 0.178 **1329.380** 0.178 {method 'readlines' of 'file' objects}
Из-за этого время, затраченное моим кодом, не линейно масштабируется по мере увеличения ввода. Я прочитал некоторые примечания к doc на readlines()
, где люди утверждали, что этот readlines()
читает весь файл в памяти и, следовательно, обычно потребляет больше памяти по сравнению с readline()
или read()
.
Я согласен с этим моментом, но если сборщик мусора автоматически очистит загруженный контент из памяти в конце моего цикла, значит, в любой момент моя память должна иметь только содержимое моего текущего обработанного файла? Но здесь есть какая-то уловка. Может кто-нибудь дать некоторое понимание этой проблемы.
Является ли это неотъемлемым поведением readlines()
или неправильной интерпретации сборщика мусора python. Рад знать.
Кроме того, предложите несколько альтернативных способов сделать то же самое в памяти и эффективно. ТИА.