diff --git a/AK/Tests/TestVector.cpp b/AK/Tests/TestVector.cpp index 88a53ba9fe8..ab619cc6885 100644 --- a/AK/Tests/TestVector.cpp +++ b/AK/Tests/TestVector.cpp @@ -167,4 +167,18 @@ TEST_CASE(vector_compare) EXPECT_EQ(strings, same_strings); } +BENCHMARK_CASE(vector_append_trivial) +{ + // This should be super fast thanks to Vector using memmove. + Vector ints; + for (int i = 0; i < 1000000; ++i) { + ints.append(i); + } + for (int i = 0; i < 100; ++i) { + Vector tmp; + tmp.append(ints); + EXPECT_EQ(tmp.size(), 1000000); + } +} + TEST_MAIN(Vector) diff --git a/AK/Vector.h b/AK/Vector.h index 631efdb0649..025ac96ba92 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -142,8 +142,8 @@ public: Vector(const Vector& other) { ensure_capacity(other.size()); - for (int i = 0; i < other.size(); ++i) - unchecked_append(other[i]); + TypedTransfer::copy(data(), other.data(), other.size()); + m_size = other.size(); } // FIXME: What about assigning from a vector with lower inline capacity? @@ -311,8 +311,8 @@ public: if (this != &other) { clear(); ensure_capacity(other.size()); - for (const auto& v : other) - unchecked_append(v); + TypedTransfer::copy(data(), other.data(), other.size()); + m_size = other.size(); } return *this; } @@ -323,17 +323,18 @@ public: *this = move(other); return; } + auto other_size = other.size(); Vector tmp = move(other); - grow_capacity(size() + tmp.size()); - for (auto&& v : tmp) - unchecked_append(move(v)); + grow_capacity(size() + other_size); + TypedTransfer::move(data() + m_size, tmp.data(), other_size); + m_size += other_size; } void append(const Vector& other) { grow_capacity(size() + other.size()); - for (auto& value : other) - unchecked_append(value); + TypedTransfer::copy(data() + m_size, other.data(), other.size()); + m_size += other.m_size; } template