Reduce allocations in lzma_encoder
Every time we flushed, we were freeing the buffer and then re-allocating
it. The usage pattern has a very constant memory usage and no peaks, so
a free list will reduce fragmentation and prevent us from thrashing the
allocator.
Change-Id: I82060dff1fe95c950e39b1bef0955e20abc5b99a
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/aos/events/logging/lzma_encoder.cc b/aos/events/logging/lzma_encoder.cc
index f354638..d348b70 100644
--- a/aos/events/logging/lzma_encoder.cc
+++ b/aos/events/logging/lzma_encoder.cc
@@ -84,6 +84,13 @@
// efficient to allocate if we go over a threshold to keep the static memory
// in use smaller, or just allocate the worst case like we are doing here?
input_buffer_.resize(max_message_size);
+
+ // Start our queues out with a reasonable space allocation. The cost of this
+ // is negligable compared to the buffer cost, but removes a bunch of
+ // allocations at runtime.
+ queue_.reserve(4);
+ free_queue_.reserve(4);
+ return_queue_.reserve(4);
}
LzmaEncoder::~LzmaEncoder() { lzma_end(&stream_); }
@@ -111,6 +118,9 @@
void LzmaEncoder::Clear(const int n) {
CHECK_GE(n, 0);
CHECK_LE(static_cast<size_t>(n), queue_size());
+ for (int i = 0; i < n; ++i) {
+ free_queue_.emplace_back(std::move(queue_[i]));
+ }
queue_.erase(queue_.begin(), queue_.begin() + n);
if (queue_.empty()) {
stream_.next_out = nullptr;
@@ -155,8 +165,13 @@
// construction or a Reset, or when an input buffer is large enough to fill
// more than one output buffer.
if (stream_.avail_out == 0) {
- queue_.emplace_back();
- queue_.back().resize(kEncodedBufferSizeBytes);
+ if (!free_queue_.empty()) {
+ queue_.emplace_back(std::move(free_queue_.back()));
+ free_queue_.pop_back();
+ } else {
+ queue_.emplace_back();
+ queue_.back().resize(kEncodedBufferSizeBytes);
+ }
stream_.next_out = queue_.back().data();
stream_.avail_out = kEncodedBufferSizeBytes;
// Update the byte count.
diff --git a/aos/events/logging/lzma_encoder.h b/aos/events/logging/lzma_encoder.h
index b4964fb..3136d93 100644
--- a/aos/events/logging/lzma_encoder.h
+++ b/aos/events/logging/lzma_encoder.h
@@ -54,6 +54,11 @@
lzma_stream stream_;
uint32_t compression_preset_;
std::vector<ResizeableBuffer> queue_;
+ // Since we pretty much just allocate a couple of buffers, then allocate and
+ // release them over and over with very similar memory usage and without much
+ // variation in the peak usage, put the allocate chunks in a free queue to
+ // reduce fragmentation.
+ std::vector<ResizeableBuffer> free_queue_;
bool finished_ = false;
// Total bytes that resulted from encoding raw data since the last call to
// Reset.