Как лучше форматировать строки в логах?
Я очень рад, что вы предоставляете мне обратную связь и интересные вопросы. Спасибо Максиму за сегодняшнюю тему!
Итак, вопрос:
В одном из последних твоих постов был пример кода с логгированием чего-то, где ты использовал f-строки для формирования сообщения для логов. В доке говорится о классной оптимизации логов путем прокидывания туда параметров с помощью %, а именно: logger.info("My param: %s", some_param)
В посте ты просто в качестве примера f-строки использовал, или у тебя есть свое мнение насчет этого?
Конечно, есть.
1) Beautiful is better than ugly.
2) There should be one-- and preferably only one --obvious way to do it.
Давайте разберем байткод:
import dis
dis.dis("a=1;f'{a}'")
print('\n\r')
dis.dis("a=1;'1 %s', a")
1‧‧‧‧‧‧‧‧ 0 LOAD_CONST‧‧‧‧‧‧‧‧‧‧‧‧ 0 (1)
‧‧‧‧‧‧‧‧‧‧‧‧ 2 STORE_NAME‧‧‧‧‧‧‧‧‧‧‧‧ 0 (a)
‧‧‧‧‧‧‧‧‧‧‧‧ 4 LOAD_NAME‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧0 (a)
‧‧‧‧‧‧‧‧‧‧‧‧ 6 FORMAT_VALUE‧‧‧‧‧‧‧‧‧‧‧‧ 0
‧‧‧‧‧‧‧‧‧‧‧‧ 8 POP_TOP
‧‧‧‧‧‧‧‧‧‧‧‧ 10 LOAD_CONST‧‧‧‧‧‧‧‧‧‧‧‧ 1 (None)
‧‧‧‧‧‧‧‧‧‧‧‧ 12 RETURN_VALUE
1‧‧‧‧‧‧‧‧ 0 LOAD_CONST‧‧‧‧‧‧‧‧‧‧‧‧ 0 (1)
‧‧‧‧‧‧‧‧‧‧‧‧ 2 STORE_NAME‧‧‧‧‧‧‧‧‧‧‧‧ 0 (a)
‧‧‧‧‧‧‧‧‧‧‧‧ 4 LOAD_CONST‧‧‧‧‧‧‧‧‧‧‧‧ 1 ('1 %s')
‧‧‧‧‧‧‧‧‧‧‧‧ 6 LOAD_NAME‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧0 (a)
‧‧‧‧‧‧‧‧‧‧‧‧ 8 BUILD_TUPLE‧‧‧‧‧‧‧‧‧‧‧‧ 2
‧‧‧‧‧‧‧‧‧‧‧‧ 10 POP_TOP
‧‧‧‧‧‧‧‧‧‧‧‧ 12 LOAD_CONST‧‧‧‧‧‧‧‧‧‧‧‧ 2 (None)
‧‧‧‧‧‧‧‧‧‧‧‧ 14 RETURN_VALUE
Мы видим, что f-строка эффективней как минимум по байткоду и на мой взгляд, по выразительности.
Проверим скорость выполнения:
import timeit
print(timeit.timeit("a=1;f'{a}'"))
print(timeit.timeit("a=1;'1 %s', a"))
(На всякий случай, я сделал каждое измерение 1000 раз и посчитал среднее).
0.03566818534678896
0.06119982904828794
К сожалению, f-строка почти вдвое медленней по времени.
Что, собственно говоря, лично мне абсолютно безразлично, так как это не самая первая вещь, которая будет меня беспокоить в случае необходимости оптимизации. Если основная цель моей программы - делать что-то ещё, кроме записи в лог.
В целом, куда больше времени будет потрачено на I/O операции, чем на преобразование строки, и в этом случае, возможно, лучшим решением будет использовать запись в sys.stdout и перенаправление вывода. Но это будет уже не так красиво и гибко, как в loguru. И это без учета времени, которое потратит на вывод сам loguru (рекомендую) или другой логгер.
Однако, на этом я не успокоился и включил "режим душнилы".
Об этом в следующем посте.
#отподписчика, #посложнее





