From b823618e0007cea7a94f421ce23adbd171b62758 Mon Sep 17 00:00:00 2001 From: Odysseas Georgoudis Date: Sat, 14 Sep 2024 22:41:34 +0100 Subject: [PATCH] Optimize TransitEventBuffer expansion --- include/quill/backend/TransitEvent.h | 5 ++++- include/quill/backend/TransitEventBuffer.h | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/quill/backend/TransitEvent.h b/include/quill/backend/TransitEvent.h index 634d219c..5dca084b 100644 --- a/include/quill/backend/TransitEvent.h +++ b/include/quill/backend/TransitEvent.h @@ -31,7 +31,7 @@ class LoggerBase; struct TransitEvent { /***/ - TransitEvent() { formatted_msg.reserve(32); } + TransitEvent() = default; /***/ ~TransitEvent() = default; @@ -81,6 +81,9 @@ struct TransitEvent return (macro_metadata->log_level() != LogLevel::Dynamic) ? macro_metadata->log_level() : dynamic_log_level; } + /***/ + void reserve_formatted_msg(size_t capacity) { formatted_msg.reserve(capacity); } + uint64_t timestamp{0}; MacroMetadata const* macro_metadata{nullptr}; detail::LoggerBase* logger_base{nullptr}; diff --git a/include/quill/backend/TransitEventBuffer.h b/include/quill/backend/TransitEventBuffer.h index f1a19d75..7c727b2e 100644 --- a/include/quill/backend/TransitEventBuffer.h +++ b/include/quill/backend/TransitEventBuffer.h @@ -28,6 +28,10 @@ class TransitEventBuffer _storage(std::make_unique(_capacity)), _mask(_capacity - 1u) { + for (size_t i = 0; i < _capacity; ++i) + { + _storage.get()[i].reserve_formatted_msg(32); + } } TransitEventBuffer(TransitEventBuffer const&) = delete; @@ -108,13 +112,22 @@ class TransitEventBuffer auto new_storage = std::make_unique(new_capacity); - // Copy existing elements to the new storage + // Move existing elements from the old storage to the new storage. + // Since the buffer is full, this moves all the previous TransitEvents, preserving their order. + // The reader position and mask are used to handle the circular buffer's wraparound. size_t const current_size = size(); for (size_t i = 0; i < current_size; ++i) { new_storage[i] = std::move(_storage[(_reader_pos + i) & _mask]); } + // For the new elements in the expanded buffer, reserve memory for formatted messages. + // This mirrors the pre-allocation done in the constructor + for (size_t i = current_size; i < new_capacity; ++i) + { + new_storage.get()[i].reserve_formatted_msg(32); + } + _storage = std::move(new_storage); _capacity = new_capacity; _mask = _capacity - 1;