Выжимание производительности из обработки большого объема

#python #string #multithreading #replace #database-metadata

Вопрос:

Я пишу сценарий, который обрабатывает отредактированные метаданные фотографий для генеалогического проекта. В рамках этого я использую exiftool для чтения метаданных фотографий, а затем сохраняю их в виде строки json в базе данных sqlite.

Когда я загружаю скрипт, он выбирает все записи из базы данных, преобразует json в dict, а затем для каждой строки в dict запускает простой скрипт обработки текста. Все это не требует больших затрат процессора, это просто большой объем, но большую часть времени скрипт тратит на обработку текста.

Прямо сейчас я загружаю около 20 тысяч фотографий, и каждая из них содержит 100-200 полей метаданных, которые необходимо проанализировать при загрузке. Итак, мы говорим о 3 звонках на эту линию:

group_tag = key.replace("::", "-") ":" n.split(":")[1]

* (Над метаданными проделана еще кое-какая работа, но на строку выше приходится 70% загрузки процессора на поток)

Я экспериментировал с потоковой обработкой / обработкой. Я смог увеличить производительность примерно на 20%, используя каждый вызов файла с пулом (ядер процессора * 4). Я перепробовал все от 1x до 10x и остановился на 4x, чтобы дать наибольший толчок. (первоначально ~16 секунд с одним потоком, теперь ~13 секунд… не такая уж большая выгода)

Однако это касается только каждого процесса обработки файлов, а не отдельной обработки строк. Так что что-то вроде этого:

 1) Read all lines (file records) from DB into memory
2) Pass each line (file record) to a processing function. <- This is threaded
2a) Threaded - Convert the json metadata into a dict
2b) For each line in the dict, run line above and push it into a new dict.
3) Collect all the results into a list in memory
 

Кое-какие мысли у меня есть:

  • Загружайте файлы без обработки, обрабатывайте только по мере необходимости.
    • Это сэкономило бы много времени заранее при обмене, передав его позже в сценарии.
    • Быстрее запустить скрипт, но работа с пакетами файлов может быть медленнее
    • Сложнее управлять в коде
  • Подзаголовок манипуляции со строками.
    • Не уверен, что создание потоков из потоков-лучшая практика. Или даже помогло бы
  • Храните обработанные данные в БД
    • Я начал делать это за счет значительно большего размера БД. 22 тыс. файлов без предварительной обработки-это около 600 Мб данных, при предварительной обработке-около 1 Гб. (Над метаданными проделана еще кое-какая работа, но на эту строку выше приходится 70% загрузки процессора на поток)
  • Как-то оптимизируйте манипуляции со строками
    • Обработать как текст перед загрузкой в формате json?
    • Векторизация редактирования строк?
    • Использовать другую библиотеку, написанную на C?
    • Другие идеи?

Короче говоря, есть какие-нибудь идеи о том, как оптимизировать подобный процесс? Все это находится в памяти (привязано к памяти?), около 3 млн изменений в пакетах по 150 на файл). Большой объем процессов с низкой загрузкой процессора.

Комментарии:

1. У меня такое чувство, что этот вопрос не по теме. Вы не опубликовали ни одного примера кода или примеров, которые мы могли бы попробовать, и на этом этапе вы, вероятно, получите в лучшем случае теоретические комментарии. Похоже, у вас уже есть некоторые идеи, такие как векторизация процесса, возможно, попробуйте их.