У меня есть функция, которая делает следующее:
- Возьмите файл в качестве ввода и выполните базовую очистку.
- Извлеките необходимые элементы из файла, а затем запишите их в кадр данных pandas.
- Фрейм данных окончательно преобразуется в csv и записывается в папку.
Это пример кода:
def extract_function(filename):
with open(filename,'r') as f:
input_data=f.readlines()
try:
// some basic searching pattern matching extracting
// dataframe creation with 10 columns and then extracted values are filled in
empty dataframe
// finally df.to_csv()
if __name__ == '__main__':
pool_size = multiprocessing.cpu_count()
filenames=os.listdir("/home/Desktop/input")
pool=multiprocessing.Pool(pool_size)
pool.map(extract_function,filenames)
pool.close()
pool.join()
Общее количество файлов в папке input : 4000
. Я использовал многопроцессорность, так как запуск программы в обычном режиме с for loop занимал некоторое время. Ниже приведены времена выполнения обоих подходов:
Обычная обработка ЦП = 139,22 секунды
Многопроцессорная обработка = 18,72 секунды
Моя системная спецификация:
Intel i5 7-го поколения, оперативная память 12 ГБ, жесткий диск 1 ТБ, Ubuntu 16.04
При запуске программы для 4000 файлов все ядра полностью используются (в среднем около 90% каждого ядра). Поэтому я решил увеличить размер файла и повторить процесс. На этот раз номер входного файла был увеличен с 4000
до 1,20,000
. Но на этот раз при запуске кода загрузка процессора была нестабильной при запуске, и через некоторое время загрузка снизилась (в среднем около 10% на ядро). Использование оперативной памяти также является низким усреднением при максимуме 4 ГБ (оставаясь свободным 8 ГБ). С 4000 файлами в качестве входных данных запись файла в CSV была быстрой, как в одно мгновение, так как я мог видеть скачок или около 1000 файлов или более в одно мгновение. Но с 1,20000 файлов в качестве входных данных, запись файлов замедлилась примерно до 300 файлов, и это замедление идет линейно, и через некоторое время запись файлов на мгновение стала около 50-70. Все это время большинство баранов свободны. Я перезапустил машину и попробовал то же самое, чтобы очистить любой нежелательный процесс зомби, но все равно, результат тот же.
В чем причина этого? Как мне добиться такой же многопроцессорности для больших файлов?
Примечание:
* Средний размер каждого файла около 300 КБ.
Каждый записываемый файл будет иметь размер около 200 байт.
* Общее количество файлов 4080. Следовательно, общий размер будет ~ 1,2 ГБ.
* Эти же 4080 файлов использовались для создания копий, чтобы получить 1,20000 файлов.
* Эта программа является экспериментом для проверки многопроцессорности на наличие большого количества файлов.
Обновление 1
Я пробовал тот же код на гораздо более мощной машине.
Intel i7 8-го поколения 8700, 1 ТБ SSHD и 60 ГБ оперативной памяти.
. Запись файла была намного быстрее, чем на обычном жестком диске. Программа заняла:
- Для 4000 файлов - 3,7 с
- Для 1,20000 файлов - 2 минуты
В какой-то момент эксперимента я получил самое быстрое время завершения, которое составляет 84 с. В тот момент он давал мне постоянный результат, пытаясь два раза подряд. Подумав, что это может быть из-за того, что я правильно установил число потоков в размере пула, я перезапустил и попытался снова. Но на этот раз это было намного медленнее. Чтобы дать представление, во время обычных прогонов около 3000-4000 файлов будут записываться в секунду или две, но на этот раз он записывал менее 600 файлов в секунду. В этом случае также оперативная память не использовалась вообще. Процессор, несмотря на то, что используется многопроцессорный модуль, загрузка всех ядер составляет в среднем около 3-7%.