From d464a071dabdfafdd7bfc5a70c3419dbe749b84e Mon Sep 17 00:00:00 2001 From: Herman Semenov Date: Wed, 31 May 2023 20:24:08 +0300 Subject: [PATCH] Optimize inserts in vector and refactor const reference objects (#659) Signed-off-by: German Semenov Co-authored-by: ArthurSonzogni --- src/ftxui/component/container.cpp | 2 ++ src/ftxui/component/input.cpp | 3 ++- src/ftxui/component/menu.cpp | 8 ++++++-- src/ftxui/component/radiobox.cpp | 1 + src/ftxui/dom/flexbox.cpp | 1 + src/ftxui/dom/flexbox_helper.cpp | 3 +++ src/ftxui/dom/gridbox.cpp | 2 ++ src/ftxui/dom/linear_gradient.cpp | 2 +- src/ftxui/dom/table.cpp | 2 ++ src/ftxui/dom/util.cpp | 1 + 10 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/ftxui/component/container.cpp b/src/ftxui/component/container.cpp index 3bd72c8..b2dc602 100644 --- a/src/ftxui/component/container.cpp +++ b/src/ftxui/component/container.cpp @@ -98,6 +98,7 @@ class VerticalContainer : public ContainerBase { Element Render() override { Elements elements; + elements.reserve(children_.size()); for (auto& it : children_) { elements.push_back(it->Render()); } @@ -180,6 +181,7 @@ class HorizontalContainer : public ContainerBase { Element Render() override { Elements elements; + elements.reserve(children_.size()); for (auto& it : children_) { elements.push_back(it->Render()); } diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp index 7275b12..a854614 100644 --- a/src/ftxui/component/input.cpp +++ b/src/ftxui/component/input.cpp @@ -117,7 +117,7 @@ class InputBase : public ComponentBase { } Elements elements; - std::vector lines = Split(*content_); + const std::vector lines = Split(*content_); int& cursor_position = option_->cursor_position(); cursor_position = util::clamp(cursor_position, 0, (int)content_->size()); @@ -138,6 +138,7 @@ class InputBase : public ComponentBase { elements.push_back(text("") | focused); } + elements.reserve(lines.size()); for (size_t i = 0; i < lines.size(); ++i) { const std::string& line = lines[i]; diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp index 03495bb..1b693b4 100644 --- a/src/ftxui/component/menu.cpp +++ b/src/ftxui/component/menu.cpp @@ -27,7 +27,7 @@ namespace { Element DefaultOptionTransform(const EntryState& state) { std::string label = (state.active ? "> " : " ") + state.label; // NOLINT - Element e = text(label); + Element e = text(std::move(label)); if (state.focused) { e = e | inverted; } @@ -114,6 +114,7 @@ class MenuBase : public ComponentBase { if (option_->elements_prefix) { elements.push_back(option_->elements_prefix()); } + elements.reserve(size()); for (int i = 0; i < size(); ++i) { if (i != 0 && option_->elements_infix) { elements.push_back(option_->elements_infix()); @@ -362,7 +363,10 @@ class MenuBase : public ComponentBase { animator_background_.clear(); animator_foreground_.clear(); - for (int i = 0; i < size(); ++i) { + const int len = size(); + animator_background_.reserve(len); + animator_foreground_.reserve(len); + for (int i = 0; i < len; ++i) { animation_background_[i] = 0.F; animation_foreground_[i] = 0.F; animator_background_.emplace_back(&animation_background_[i], 0.F, diff --git a/src/ftxui/component/radiobox.cpp b/src/ftxui/component/radiobox.cpp index 94f8157..10f4bf0 100644 --- a/src/ftxui/component/radiobox.cpp +++ b/src/ftxui/component/radiobox.cpp @@ -33,6 +33,7 @@ class RadioboxBase : public ComponentBase { Clamp(); Elements elements; const bool is_menu_focused = Focused(); + elements.reserve(size()); for (int i = 0; i < size(); ++i) { const bool is_focused = (focused_entry() == i) && is_menu_focused; const bool is_selected = (hovered_ == i); diff --git a/src/ftxui/dom/flexbox.cpp b/src/ftxui/dom/flexbox.cpp index 9a27673..8c1ce2c 100644 --- a/src/ftxui/dom/flexbox.cpp +++ b/src/ftxui/dom/flexbox.cpp @@ -68,6 +68,7 @@ class Flexbox : public Node { void Layout(flexbox_helper::Global& global, bool compute_requirement = false) { + global.blocks.reserve(children_.size()); for (auto& child : children_) { flexbox_helper::Block block; block.min_size_x = child->requirement().min_x; diff --git a/src/ftxui/dom/flexbox_helper.cpp b/src/ftxui/dom/flexbox_helper.cpp index bb55726..37cd2b7 100644 --- a/src/ftxui/dom/flexbox_helper.cpp +++ b/src/ftxui/dom/flexbox_helper.cpp @@ -88,6 +88,7 @@ struct Line { void SetX(Global& global, std::vector lines) { for (auto& line : lines) { std::vector elements; + elements.reserve(line.blocks.size()); for (auto* block : line.blocks) { box_helper::Element element; element.min_size = block->min_size_x; @@ -117,6 +118,7 @@ void SetX(Global& global, std::vector lines) { // NOLINTNEXTLINE(readability-function-cognitive-complexity) void SetY(Global& g, std::vector lines) { std::vector elements; + elements.reserve(lines.size()); for (auto& line : lines) { box_helper::Element element; element.flex_shrink = line.blocks.front()->flex_shrink_y; @@ -317,6 +319,7 @@ void Compute3(Global& global) { { Line line; int x = 0; + line.blocks.reserve(global.blocks.size()); for (auto& block : global.blocks) { // Does it fit the end of the row? // No? Then we need to start a new one: diff --git a/src/ftxui/dom/gridbox.cpp b/src/ftxui/dom/gridbox.cpp index 7acbc63..46d21cb 100644 --- a/src/ftxui/dom/gridbox.cpp +++ b/src/ftxui/dom/gridbox.cpp @@ -37,6 +37,8 @@ class GridBox : public Node { for (const auto& line : lines_) { x_size = std::max(x_size, int(line.size())); } + + // Fill in empty cells, in case the user did not used the API correctly: for (auto& line : lines_) { while (line.size() < size_t(x_size)) { line.push_back(filler()); diff --git a/src/ftxui/dom/linear_gradient.cpp b/src/ftxui/dom/linear_gradient.cpp index 45b27ce..031228f 100644 --- a/src/ftxui/dom/linear_gradient.cpp +++ b/src/ftxui/dom/linear_gradient.cpp @@ -78,7 +78,7 @@ LinearGradientNormalized Normalize(LinearGradient gradient) { LinearGradientNormalized normalized; // NOLINTNEXTLINE normalized.angle = std::fmod(std::fmod(gradient.angle, 360.f) + 360.f, 360.f); - for (auto& stop : gradient.stops) { + for (const auto& stop : gradient.stops) { normalized.colors.push_back(stop.color); normalized.positions.push_back(stop.position.value()); // NOLINT } diff --git a/src/ftxui/dom/table.cpp b/src/ftxui/dom/table.cpp index e6b77d2..4397477 100644 --- a/src/ftxui/dom/table.cpp +++ b/src/ftxui/dom/table.cpp @@ -44,9 +44,11 @@ Table::Table() { Table::Table(std::vector> input) { std::vector> output; + output.reserve(input.size()); for (auto& row : input) { output.emplace_back(); auto& output_row = output.back(); + output_row.reserve(row.size()); for (auto& cell : row) { output_row.push_back(text(std::move(cell))); } diff --git a/src/ftxui/dom/util.cpp b/src/ftxui/dom/util.cpp index 90c311a..e585631 100644 --- a/src/ftxui/dom/util.cpp +++ b/src/ftxui/dom/util.cpp @@ -46,6 +46,7 @@ Decorator operator|(Decorator a, Decorator b) { /// @ingroup dom Elements operator|(Elements elements, Decorator decorator) { // NOLINT Elements output; + output.reserve(elements.size()); for (auto& it : elements) { output.push_back(std::move(it) | decorator); }