Медленное открытие файлов в python

В настоящее время я пишу программу, которая должна загружать более 13 000 файлов «*.json» разных размеров от нескольких строк до 100 000 строк. Чтение выглядит так:

[read_one_JSON(p) for p in filenames]

def read_one_JSON(path: str):
    with open(path, encoding='utf-8') as fh:
        data = json.load(fh)
        return File(data["_File__name"], data['_File__statements'], data['_File__matches'])

Я загружаю файл, передаю его в класс File и читаю другой файл. В настоящее время это занимает около 2 минут 20 секунд. Я обнаружил, что когда я убираю обработку данных в класс и делаю просто:

[read_one_JSON(p) for p in filenames]

def read_one_JSON(path: str):
    with open(path, encoding='utf-8') as fh:
        data = json.load(fh)

Это сокращает время всего на 10 секунд до 2 минут и 10 секунд. Итак, затем я также удалил json.load, чтобы увидеть, что вызывает время чтения. Итак, при выезде просто:

[read_one_JSON(p) for p in filenames]

def read_one_JSON(path: str):
    with open(path, encoding='utf-8') as fh:

и не считывая данные, он все еще длится 1 минуту 45 секунд. Это означает, что открытие файлов происходит медленно. Есть ли способ ускорить начальную часть процесса, не помещая все в один файл или распараллеливая? Это вариант, но я хотел бы знать, можно ли с этим что-то еще сделать.

Раньше я осознавал такое узкое место, я пробовал библиотеки, такие как ujson, orjson, msgpec, но, поскольку фаза открытия медленная, это имело лишь небольшие различия.

Это может быть хорошим случаем для multiprocessing. Почему нет распараллеливания?

Andrej Kesely 27.11.2022 22:04

Это так, и я подаю заявку multiprocessing в другой части программы. Сейчас мне просто интересно, существует ли что-то еще, о чем я еще не слышал, возможно, нет, так как я ничего не мог найти об этом. Если не будет ничего другого, я буду использовать многопроцессорность (возможно, даже когда я найду другое решение), я студент CS, поэтому каждое новое знание ценно.

Juraj 27.11.2022 22:10

Посмотрите, какая именно операция выполняется медленно — если это проблема с файловой системой, f/e, ее следует решать на уровне файловой системы, а не путем изменения кода Python вообще.

Charles Duffy 27.11.2022 22:37

13K файлов за 105 секунд соответствует примерно 0,008 секунды на файл. Одна десятитысячная секунды не кажется особенно медленной.

ekhumoro 27.11.2022 22:38

Если вам нужен инструмент, который может выполнять трассировку с минимальными затратами для соответствующего анализа, я настоятельно рекомендую sysdig; он имеет встроенные «резцы» — Lua-скрипты, способные выполнять различные виды анализа, включая выявление операций с высокой задержкой.

Charles Duffy 27.11.2022 22:39

Кстати, в зависимости от особенностей проводимого вами анализа вы можете подумать о переключении с набора отдельных файлов на индексированную базу данных. Существуют хранилища документов, хорошо оптимизированные для запросов к большим коллекциям документов с аналогичной структурой.

Charles Duffy 27.11.2022 22:41
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
6
139
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Создание 13000 файлов в текущем каталоге:

import json

from tqdm import tqdm  # pip install tqdm

for i in tqdm(range(13_000)):
    filename = f"data_{i}.json"
    data = {"filename": filename}
    with open(filename, "w") as file:
        json.dump(data, file)
100%|██████████| 13000/13000 [00:01<00:00, 8183.74it/s]

Это означает, что на моем компьютере он работал менее 2 секунд. tqdm — это очень простой способ увидеть пропускную способность. Скрипт создал такие файлы, как:

{"filename": "data_0.json"}

Затем читаем их:

import json

from tqdm import tqdm  # pip install tqdm

for i in tqdm(range(13_000)):
    filename = f"data_{i}.json"
    with open(filename, "rt") as file:
        data = json.load(file)
print(data)
100%|██████████| 13000/13000 [00:00<00:00, 16472.00it/s]
{'filename': 'data_12999.json'}

Это означает, что все они были прочитаны менее чем за одну секунду.

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

Другие вопросы по теме