Цикл колбы занимает много времени для завершения

#python #python-requests

Вопрос:

У меня есть эта петля в моем app.py. По какой-то причине это увеличивает время загрузки более чем на 3 секунды. Есть ли какие-то решения?

 import dateutil.parser as dp

# Converts date from ISO-8601 string to formatted string and returns it
def dateConvert(date):
    return dp.parse(date).strftime("%H:%M @ %e/%b/%y")

def nameFromID(userID):
    if userID is None:
       return 'Unknown'
    else:
       response = requests.get("https://example2.org/"   str(userID), headers=headers)
       return response.json()['firstName']   ' '   response.json()['lastName']

logs = []
response = requests.get("https://example.org", headers=headers)
for response in response.json():
    logs.append([nameFromID(response['member']), dateConvert(response['createdAt'])])
 

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

1. Что делать nameFromID и dateConvert что делать? (Пожалуйста, добавьте их в свой вопрос.) Насколько нам известно, они оба являются интерфейсами time.sleep() .

2. Вы уверены, что проблема в петле? Может быть, это requests.get вызов или любой из вызовов внутри цикла ( logs.append , nameFromId , dataConvert )? Если ваш код медленный и вы не знаете почему, изучите профилирование на Python — вероятно, существует множество полезных инструментов для вашей конкретной веб-платформы.

Ответ №1:

Это увеличивает время загрузки более чем на 3 секунды, потому что это делает много ненужной работы, вот почему.

  • Вы не используете requests сеансы. Для каждого запроса потребуется создать и отключить HTTPS-соединение. Это медленно.
  • Вы выполняете еще один HTTPS — запрос для каждого преобразования имени. (См. выше.)
    • Вы дважды анализируете JSON, который получаете в этой функции.
  • Что бы это ни dp.parse() было ( dateutil ?), оно, вероятно, выполняет много дополнительной работы по анализу строки свободной формы. Если вы знаете формат ввода, используйте strptime .

Вот переделка, которая должна быть значительно быстрее. Пожалуйста, сначала ознакомьтесь с пунктами задач, конечно.

Кроме того, если вы вольны знать, что идентификатор участника -> сопоставление имен не меняется, вы также можете создать name_cache глобальную переменную с подходящим именем (но помните, что она может сохраняться между запросами).

 import datetime
import requests

INPUT_DATE_FORMAT = "TODO_FILL_ME_IN"  # TODO: FILL ME IN.


def dateConvert(date: str):
    return datetime.datetime.strptime(date, INPUT_DATE_FORMAT).strftime(
        "%H:%M @ %e/%b/%y"
    )


def nameFromID(sess: requests.Session, userID):
    if userID is None:
        return "Unknown"
    response = sess.get(f"https://example2.org/{userID}")
    response.raise_for_status()
    data = response.json()
    return "{firstName} {lastName}".format_map(data)


def do_thing():
    headers = {}  # TODO: fill me in
    name_cache = {}
    with requests.Session() as sess:
        sess.headers.update(headers)

        logs = []
        response = sess.get("https://example.org")
        for response in response.json():
            member_id = response["member"]
            name = name_cache.get(member_id)
            if not name:
                name = name_cache[member_id] = nameFromID(sess, member_id)
            logs.append([name, dateConvert(response["createdAt"])])
 

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

1. Эй, извини за мой грязный код. Я новичок в python и колбе в целом. Спасибо вам за ваш ответ. Я постараюсь разобраться в этом.

2. Все в порядке, не нужно извиняться (хотя, как вы могли видеть, больше контекста сделало ответ на самом деле возможным 🙂 )! Добро пожаловать в SO, Питон и Колбу! Рад, что смог помочь.