2015-12-21 3 views
1

У меня есть сценарий, который делает некоторые кэширование бедных людей данными, возвращаемыми из API, в плоский файл как объекты JSON. Один результат/объект JSON в строке.Как оптимизировать чтение и работу над большим файлом?

Рабочий процесс кэширования заключается в следующем:

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

На сегодняшний день самая длинная часть этого процесса выделена полужирным шрифтом. Вот код:

print "Reading cache file into memory ---" 
with open('cache', 'r') as f: 
    cache_lines = f.readlines() 

print "Turning cache lines into json and checking if they are stale or not ---" 
for line in cache_lines 
    # Load the line back up as a json object 
    try: 
     json_line = json.loads(line) 
    except Exception as e: 
     print e 

    # Get the delta to determine if data is stale. 
    delta = meta_dict["timestamp_start"] - parser.parse(json_line['timestamp_start']) 

    # If the data is still fresh then hold onto it 
    if cache_timeout >= delta: 
     fresh_cache.append(json_line) 

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

ответ

1

В зависимости от вашего размера файла могут возникнуть проблемы с памятью. Я не знаю, является ли это той проблемой, с которой вы сталкиваетесь. Предыдущий код можно переписать так:

delta = meta_dict['timestamp_start'] 
with open('cache', 'r') as f: 
    while True: 
     line = f.readline() 
     if not line: 
      break 
     line = json.loads(line) 
     if delta - parser.parse(line['timestamp_start']) <= cache_timeout: 
      fresh_cache.append(json_line) 

Кроме того,

  • не то, что если вы используете dateutils разобрать дату, каждый вызов может быть дорогостоящим. Если ваш формат известен, вы можете использовать стандартные инструменты преобразования, предоставляемые datetime или dateutils
  • если ваш файл действительно большой и fresh_cache должен быть очень большим, то вы можете написать свежие записи на промежуточный файл с помощью другого with заявление.
+0

Спасибо за ввод. Я надеялся на какую-то черную магию, но похоже, что мне не повезло. Я попробую не parser.parsing каждый звонок и посмотреть, поможет ли это. – Thisisstackoverflow

+0

вы также можете попробовать библиотеку 'simplejson', которая быстрее, чем стандартная библиотека' json' ... – ohe

+0

Хорошая точка. Это тоже выстрел. – Thisisstackoverflow

0

Отчетность назад - 1. simplejson не имел никакого эффекта. 2. Выполнение ручной вытяжки дат-времени имело большой эффект. Он уменьшил время от 8m11.578s до 2m55.681s. Это заменило строку parser.parse сверху: datetime.datetime.strptime (json_line ['timestamp_start'], "% Y-% m-% d % H:% M:% S.% f") -

Смежные вопросы