Index: base/value_perftest.cc |
diff --git a/base/value_perftest.cc b/base/value_perftest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b6938f9ff5d4af51d2a8355bcce15c4756c95c1c |
--- /dev/null |
+++ b/base/value_perftest.cc |
@@ -0,0 +1,175 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <algorithm> |
+#include <numeric> |
+#include <random> |
+#include <string> |
+ |
+#include "base/memory/ptr_util.h" |
+#include "base/strings/string_piece.h" |
+#include "base/time/time.h" |
+#include "base/values.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "testing/perf/perf_test.h" |
+ |
+namespace base { |
+ |
+class ValuePerfTest : public testing::Test { |
+ public: |
+ enum class TestOrder { ASCENDING, DESCENDING, INTERLEAVED, RANDOM }; |
+ |
+ std::string to_string(TestOrder order) { |
+ switch (order) { |
+ case TestOrder::ASCENDING: |
+ return "ascending"; |
+ case TestOrder::DESCENDING: |
+ return "descending"; |
+ case TestOrder::INTERLEAVED: |
+ return "interleaved"; |
+ case TestOrder::RANDOM: |
+ return "random"; |
+ default: |
+ return ""; |
+ } |
+ } |
+ |
+ std::vector<int> GetLengths(int max_length, TestOrder order) { |
+ std::vector<int> lengths(max_length + 1); |
+ std::iota(std::begin(lengths), std::end(lengths), 0); |
+ |
+ switch (order) { |
+ case TestOrder::ASCENDING: |
+ break; |
+ case TestOrder::DESCENDING: |
+ std::reverse(std::begin(lengths), std::end(lengths)); |
+ break; |
+ case TestOrder::INTERLEAVED: |
+ for (int i = 0; i < max_length / 2; i += 2) |
+ std::swap(lengths[i], lengths[max_length - i]); |
+ break; |
+ case TestOrder::RANDOM: { |
+ std::random_device rd; |
+ std::mt19937 g(rd()); |
+ std::shuffle(std::begin(lengths), std::end(lengths), g); |
+ break; |
+ } |
+ } |
+ |
+ return lengths; |
+ } |
+ |
+ void TestStringMoveAssign(int max_length, TestOrder order) { |
+ std::string description = "Max Length: " + std::to_string(max_length) + |
+ ", TestOrder: " + to_string(order); |
+ |
+ double duration = 0.0; |
+ for (auto length : GetLengths(max_length, order)) { |
+ auto val = Value(std::string(length, 'a')); |
+ TimeTicks start = TimeTicks::Now(); |
+ val_ = std::move(val); |
+ TimeTicks end = TimeTicks::Now(); |
+ duration += (end - start).InMicroseconds(); |
+ } |
+ |
+ perf_test::PrintResult("StringMoveAssign", "", description, duration, "us", |
+ true); |
+ } |
+ |
+ void TestListMoveAssign(int max_length, TestOrder order) { |
+ std::string description = "Max Length: " + std::to_string(max_length) + |
+ ", TestOrder: " + to_string(order); |
+ |
+ double duration = 0.0; |
+ for (auto length : GetLengths(max_length, order)) { |
+ auto val = ListValue(); |
+ for (int i = 0; i < length; ++i) |
+ val.AppendInteger(i); |
+ TimeTicks start = TimeTicks::Now(); |
+ val_ = std::move(val); |
+ TimeTicks end = TimeTicks::Now(); |
+ duration += (end - start).InMicroseconds(); |
+ } |
+ |
+ perf_test::PrintResult("ListMoveAssign", "", description, duration, "us", |
+ true); |
+ } |
+ |
+ void TestDictMoveAssign(int max_length, TestOrder order) { |
+ std::string description = "Max Length: " + std::to_string(max_length) + |
+ ", TestOrder: " + to_string(order); |
+ |
+ double duration = 0.0; |
+ for (auto length : GetLengths(max_length, order)) { |
+ auto val = DictionaryValue(); |
+ for (int i = 0; i < length; ++i) |
+ val.Set(std::to_string(i), MakeUnique<Value>(i)); |
+ TimeTicks start = TimeTicks::Now(); |
+ val_ = std::move(val); |
+ TimeTicks end = TimeTicks::Now(); |
+ duration += (end - start).InMicroseconds(); |
+ } |
+ |
+ perf_test::PrintResult("DictMoveAssign", "", description, duration, "us", |
+ true); |
+ } |
+ |
+ void TestSortStringValues(int max_length, TestOrder order) { |
+ std::string description = "Max Length: " + std::to_string(max_length) + |
+ ", TestOrder: " + to_string(order); |
+ |
+ std::vector<base::Value> values; |
+ values.reserve(max_length); |
+ for (auto length : GetLengths(max_length, order)) |
+ values.emplace_back(std::string(length, 'a')); |
+ |
+ TimeTicks start = TimeTicks::Now(); |
+ std::sort(std::begin(values), std::end(values), |
+ [](const base::Value& lhs, const base::Value& rhs) { |
+ return lhs.GetString() < rhs.GetString(); |
+ }); |
+ TimeTicks end = TimeTicks::Now(); |
+ double duration = (end - start).InMicroseconds(); |
+ |
+ perf_test::PrintResult("SortStringValues", "", description, duration, "us", |
+ true); |
+ } |
+ |
+ private: |
+ Value val_; |
+}; |
+ |
+TEST_F(ValuePerfTest, StringAssignTest) { |
+ for (int l = 0; l < 19; ++l) { |
+ for (int o = 0; o < 1; ++o) { |
+ TestStringMoveAssign(1 << l, static_cast<ValuePerfTest::TestOrder>(o)); |
+ } |
+ } |
+} |
+ |
+TEST_F(ValuePerfTest, ListAssignTest) { |
+ for (int l = 0; l < 15; ++l) { |
+ for (int o = 0; o < 1; ++o) { |
+ TestListMoveAssign(1 << l, static_cast<ValuePerfTest::TestOrder>(o)); |
+ } |
+ } |
+} |
+ |
+TEST_F(ValuePerfTest, DictAssignTest) { |
+ for (int l = 0; l < 14; ++l) { |
+ for (int o = 0; o < 1; ++o) { |
+ TestDictMoveAssign(1 << l, static_cast<ValuePerfTest::TestOrder>(o)); |
+ } |
+ } |
+} |
+ |
+TEST_F(ValuePerfTest, SortTest) { |
+ for (int l = 0; l < 19; ++l) { |
+ for (int o = 0; o < 4; ++o) { |
+ TestSortStringValues(1 << l, static_cast<ValuePerfTest::TestOrder>(o)); |
+ } |
+ } |
+} |
+ |
+} // namespace base |