| 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
|
|
|