| Index: base/containers/flat_set_perftest.cc
|
| diff --git a/base/containers/flat_set_perftest.cc b/base/containers/flat_set_perftest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c6f6d3fef6eb1c15859de89242647603ebb43bc4
|
| --- /dev/null
|
| +++ b/base/containers/flat_set_perftest.cc
|
| @@ -0,0 +1,166 @@
|
| +// 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 "base/containers/flat_set.h"
|
| +
|
| +#include <algorithm>
|
| +#include <numeric>
|
| +#include <random>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/strings/string_piece.h"
|
| +#include "base/time/time.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/perf/perf_test.h"
|
| +
|
| +namespace base {
|
| +enum class TestOrder { ASCENDING, DESCENDING, INTERLEAVED, RANDOM };
|
| +
|
| +enum class InputRelation { SMALLER, GREATER };
|
| +
|
| +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::string to_string(InputRelation rel) {
|
| + switch (rel) {
|
| + case InputRelation::SMALLER:
|
| + return "smaller";
|
| + case InputRelation::GREATER:
|
| + return "greater";
|
| + default:
|
| + return "";
|
| + }
|
| +}
|
| +
|
| +std::string to_string(RangeInsertMethod method) {
|
| + switch (method) {
|
| + case RangeInsertMethod::ONE_BY_ONE:
|
| + return "One By One";
|
| + case RangeInsertMethod::STABLE_SORT_ALL:
|
| + return "Stable Sort All";
|
| + case RangeInsertMethod::STABLE_SORT_SMART:
|
| + return "Stable Sort Smart";
|
| + case RangeInsertMethod::STABLE_SORT_SMARTER:
|
| + return "Stable Sort Smarter";
|
| + default:
|
| + return "";
|
| + }
|
| +}
|
| +
|
| +std::vector<int> GetInputs(int length, TestOrder order, int start = 0) {
|
| + std::vector<int> inputs(length);
|
| + std::iota(std::begin(inputs), std::end(inputs), start);
|
| +
|
| + switch (order) {
|
| + case TestOrder::ASCENDING:
|
| + break;
|
| + case TestOrder::DESCENDING:
|
| + std::reverse(std::begin(inputs), std::end(inputs));
|
| + break;
|
| + case TestOrder::INTERLEAVED:
|
| + for (int i = 0; i < length / 2; i += 2)
|
| + std::swap(inputs[i], inputs[length - 1 - i]);
|
| + break;
|
| + case TestOrder::RANDOM: {
|
| + std::random_device rd;
|
| + std::mt19937 g(rd());
|
| + std::shuffle(std::begin(inputs), std::end(inputs), g);
|
| + break;
|
| + }
|
| + }
|
| +
|
| + return inputs;
|
| +}
|
| +
|
| +void test_range_insertion(int initial_size,
|
| + int n_items,
|
| + int pct_overlap,
|
| + InputRelation rel,
|
| + TestOrder order,
|
| + RangeInsertMethod method) {
|
| + int set_start = 0;
|
| + int input_start = 0;
|
| +
|
| + if (rel == InputRelation::SMALLER) {
|
| + set_start = std::max(0.0, n_items - pct_overlap / 100.0 * initial_size);
|
| + } else {
|
| + input_start = std::max(0.0, initial_size - pct_overlap / 100.0 * n_items);
|
| + }
|
| +
|
| + flat_set<int> set(GetInputs(initial_size, TestOrder::ASCENDING, set_start),
|
| + KEEP_FIRST_OF_DUPES);
|
| + std::string description = "Initial Size: " + std::to_string(initial_size) +
|
| + "\tNumber of Items: " + std::to_string(n_items) +
|
| + "\tPct Overlap: " + std::to_string(pct_overlap) +
|
| + "\tInputRelation: " + to_string(rel) +
|
| + "\tTestOrder: " + to_string(order) +
|
| + "\tMethod: " + to_string(method);
|
| + std::vector<int> inputs = GetInputs(n_items, order, input_start);
|
| + TimeTicks start = TimeTicks::Now();
|
| + set.insert(inputs.begin(), inputs.end(), method);
|
| + TimeTicks end = TimeTicks::Now();
|
| + double duration = (end - start).InMicroseconds();
|
| + perf_test::PrintResult("RangeInsertionTest", "", description, duration, "us",
|
| + true);
|
| +}
|
| +
|
| +void test_insert_single_close_to_end(int n_items, RangeInsertMethod method) {
|
| + std::vector<int> inputs = GetInputs(n_items, TestOrder::ASCENDING);
|
| +
|
| + std::string description = "Number of Items: " + std::to_string(n_items) +
|
| + "\tMethod: " + to_string(method);
|
| + flat_set<int> set;
|
| + set.insert(inputs.back());
|
| + TimeTicks start = TimeTicks::Now();
|
| + for (auto iter = inputs.begin(); std::next(iter) != inputs.end(); ++iter) {
|
| + set.insert(iter, std::next(iter), method);
|
| + }
|
| + TimeTicks end = TimeTicks::Now();
|
| + double duration = (end - start).InMicroseconds();
|
| + perf_test::PrintResult("RangeInsertionTest", "", description, duration, "us",
|
| + true);
|
| +}
|
| +
|
| +TEST(FlatSetPerfTest, RangeInsertionTest) {
|
| + for (int i = 0; i < 16; ++i) {
|
| + for (int n = 0; n < 16; ++n) {
|
| + for (int o = 0; o <= 10; ++o) {
|
| + for (int r = 0; r < 2; ++r) {
|
| + for (int t = 0; t < 4; ++t) {
|
| + for (int m = 0; m < 4; ++m) {
|
| + test_range_insertion(
|
| + 1 << i, 1 << n, o * 10, static_cast<InputRelation>(r),
|
| + static_cast<TestOrder>(t), static_cast<RangeInsertMethod>(m));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST(FlatSetPerfTest, SingleRangeInsertionTestCloseToEnd) {
|
| + for (int i = 0; i < 16; ++i) {
|
| + for (int m : {0, 1, 2, 3}) {
|
| + test_insert_single_close_to_end(1 << i,
|
| + static_cast<RangeInsertMethod>(m));
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace base
|
|
|