Refactor container update by preferring the range insert. The range operation is generally more efficient than inserting within a loop, as it avoids having to do a capacity check each loop iteration, instead pre-allocating the necessary block of memory all at once and then doing an optimized batch insert. Change-Id: I79c5db3075c7afe71e4484e20188307deeb60a4f Reviewed-on: https://gn-review.googlesource.com/c/gn/+/20080 Reviewed-by: Sylvain Defresne <sdefresne@chromium.org> Reviewed-by: Jeffrey Yu <yuje@google.com> Commit-Queue: Jeffrey Yu <yuje@google.com>
diff --git a/src/gn/operators.cc b/src/gn/operators.cc index 7c04dd3..93cbe72 100644 --- a/src/gn/operators.cc +++ b/src/gn/operators.cc
@@ -6,6 +6,7 @@ #include <stddef.h> #include <algorithm> +#include <iterator> #include "base/strings/string_number_conversions.h" #include "gn/err.h" @@ -375,9 +376,11 @@ if (left.type() == Value::LIST && right.type() == Value::LIST) { // Since left was passed by copy, avoid realloc by destructively appending // to it and using that as the result. - for (Value& value : right.list_value()) - left.list_value().push_back(std::move(value)); - return left; // FIXME(brettw) does this copy? + auto& right_list = right.list_value(); + left.list_value().insert(left.list_value().end(), + std::make_move_iterator(right_list.begin()), + std::make_move_iterator(right_list.end())); + return left; } *err = MakeIncompatibleTypeError(op_node, left, right);