All streams
Search
Write a publication
Pull to refresh
12
0
Карелин Павел @hkarel

Программист

Send message

Я попросил коллег прогнать мои тесты. У всех Ubuntu 18.04. Тесты на 4 потока, 5 млн. записей. Первое значение Logging time, второе — Flush time (в секундах).


AMD Ryzen 7 3800X (Десктоп)
ALog: 1.47/2.23
P7: 2.43/2.86
Spdlog: 3.79/3.79


Core i5-8400 2.80GHz (Десктоп)
ALog: 1.51/2.85
P7: 5.49/5.49
Spdlog: 3.19/3.19


Core i5-8300H 2.30GHz (Ноутбук)
ALog: 3.36/5.04
P7: 13.34/14.04
Spdlog: 3.12/3.12


Нельзя сказать, что результаты идеально бьются со значениями из статьи, но по крайней мере в рамках одного процессора можно заметить корреляции. В этой связи к Lau возникает вопрос: как у него получились такие результаты? Возможно, причина в Windows, или в ключе -O3. Выяснить это можно собрав оригинальный тест/тесты под Linux, но кода тестов нет.

Я так понимаю у Вас свои варианты тестов. Код посмотреть можно?
В целом концепция понятна. Вы упоминали библиотеку quill, она реализует те механизмы, о которых Вы пишете?
1. ostream-style логгирование — это медленно. Особенно если логировать произвольные типы, которые умеют сериализоваться в std::ostream.
Действительно, первичная реализация использовала std::stringstream, сейчас только строковый буфер.

2. В вашем логгере в каждой вызове явное выделение памяти в Line (new Impl) + выделение памяти в деструкторе Line (new Message) + неявнЫЕ в std::string. Лучше использовать что-то типа ring buffer queue. Имея синтаксис printf/std::format практически всегда можно вычислить необходимое количество байт для передачи через ring buffer (есть нюансы).
Про выделение памяти явное и неявное — все верно. std::format, насколько я понимаю, доступен только с С++20, а у меня сейчас потолок С++17, да и основной формат вывода все таки потоковый.
Допустим, я буду использовать кольцевой буфер. Как определиться с его размером? Длина лог-сообщений в моих задачах варьируется от 100 символов, до 5Мб символов (бывает и больше).

3. Вместо спинлока в Logger::addMessage можно сделать N очередей для N потоков. Лок, в данном случае, будет только в момент создания очереди. В потоках использовать thread local storage.
Не очень понятна мысль про N очередей для N потоков. Вы предлагаете для каждого рабочего потока иметь свою очередь?
Конкректно фильтрации по имени класса нет, есть фильтрация по имени функции. Но практика использования логгера показала, что фильтрация по функции мало востребована, поэтому сейчас имя функции даже в лог-строку не выводится (только имя модуля и номер строки)
Добавить в текущее решение ALog фильтрацию по имени класса — возможно, но это уже будет новое решение (клон).
Два момента:
1. Появляется новая зависимость в виде boost библиотеки;
2. Предложенное решение нужно тестировать на быстродействие. DistortNeo, возьметесь?
Согласен, использование malloc может быть проблемой в плане фрагментации памяти и скорости работы. С другой стороны, пока не готов использовать различные виды кешей, боюсь попасть в ловушку SpdLog с чрезмерным выделением памяти.
Причины формата DD.MM.YYYY древние и исторические (совместимость в рамках большого проекта). Уже позднее были мысли перейти на формат YYYY.MM.DD, но железобетонных аргументов для себя не нашел. А grep неплохо справляется с обоими форматами.
2

Information

Rating
Does not participate
Location
Ярославль, Ярославская обл., Россия
Date of birth
Registered
Activity

Specialization

Application Developer, Software Architect
Lead
C++
Software development
Multiple thread
Code Optimization
Qt
OpenCV
C++ STL
Object-oriented design