From e8e85f5457a225f6387efdf1f4d9f36f93fce3fb Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 7 Aug 2019 15:05:10 +0200 Subject: [PATCH] Vector: Use memcmp for comparing two vectors with trivial elements --- AK/Tests/TestVector.cpp | 25 +++++++++++++++++++++++++ AK/Traits.h | 2 +- AK/Vector.h | 20 +++++++++++++------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/AK/Tests/TestVector.cpp b/AK/Tests/TestVector.cpp index 1405ccfb4a..88a53ba9fe 100644 --- a/AK/Tests/TestVector.cpp +++ b/AK/Tests/TestVector.cpp @@ -142,4 +142,29 @@ TEST_CASE(prepend_vector_object) EXPECT_EQ(objects[5].subobject->value, 3); } +TEST_CASE(vector_compare) +{ + Vector ints; + Vector same_ints; + + for (int i = 0; i < 1000; ++i) { + ints.append(i); + same_ints.append(i); + } + + EXPECT_EQ(ints.size(), 1000); + EXPECT_EQ(ints, same_ints); + + Vector strings; + Vector same_strings; + + for (int i = 0; i < 1000; ++i) { + strings.append(String::number(i)); + same_strings.append(String::number(i)); + } + + EXPECT_EQ(strings.size(), 1000); + EXPECT_EQ(strings, same_strings); +} + TEST_MAIN(Vector) diff --git a/AK/Traits.h b/AK/Traits.h index 0eaf5d3e86..fb5ce773d3 100644 --- a/AK/Traits.h +++ b/AK/Traits.h @@ -7,12 +7,12 @@ namespace AK { template struct GenericTraits { + static constexpr bool is_trivial() { return false; } static bool equals(const T& a, const T& b) { return a == b; } }; template struct Traits : public GenericTraits { - static constexpr bool is_trivial() { return false; } }; template<> diff --git a/AK/Vector.h b/AK/Vector.h index 21e3aa1b91..631efdb064 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -85,6 +85,18 @@ public: for (size_t i = 0; i < count; ++i) new (&destination[i]) T(source[i]); } + + static bool compare(const T* a, const T* b, size_t count) + { + if constexpr (Traits::is_trivial()) + return !memcmp(a, b, count * sizeof(T)); + + for (size_t i = 0; i < count; ++i) { + if (a[i] != b[i]) + return false; + } + return true; + } }; template @@ -178,13 +190,7 @@ public: { if (m_size != other.m_size) return false; - - for (int i = 0; i < m_size; ++i) { - if (at(i) != other.at(i)) - return false; - } - - return true; + return TypedTransfer::compare(data(), other.data(), size()); } bool operator!=(const Vector& other) const