summaryrefslogtreecommitdiffstats
path: root/chromium/base/observer_list_perftest.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:19:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:01:50 +0000
commit51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch)
tree835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/base/observer_list_perftest.cc
parent6036726eb981b6c4b42047513b9d3f4ac865daac (diff)
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/base/observer_list_perftest.cc')
-rw-r--r--chromium/base/observer_list_perftest.cc119
1 files changed, 119 insertions, 0 deletions
diff --git a/chromium/base/observer_list_perftest.cc b/chromium/base/observer_list_perftest.cc
new file mode 100644
index 00000000000..2e0e5e88c00
--- /dev/null
+++ b/chromium/base/observer_list_perftest.cc
@@ -0,0 +1,119 @@
+// Copyright 2018 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/observer_list.h"
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/observer_list.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+// Ask the compiler not to use a register for this counter, in case it decides
+// to do magic optimizations like |counter += kLaps|.
+volatile int g_observer_list_perf_test_counter;
+
+namespace base {
+
+class ObserverInterface {
+ public:
+ ObserverInterface() {}
+ virtual ~ObserverInterface() {}
+ virtual void Observe() const { ++g_observer_list_perf_test_counter; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverInterface);
+};
+
+class UnsafeObserver : public ObserverInterface {};
+
+class TestCheckedObserver : public CheckedObserver, public ObserverInterface {};
+
+template <class ObserverType>
+struct Pick {
+ // The ObserverList type to use. Checked observers need to be in a checked
+ // ObserverList.
+ using ObserverListType = ObserverList<ObserverType>;
+ static const char* GetName() { return "CheckedObserver"; }
+};
+template <>
+struct Pick<UnsafeObserver> {
+ using ObserverListType = ObserverList<ObserverInterface>::Unchecked;
+ static const char* GetName() { return "UnsafeObserver"; }
+};
+
+template <class ObserverType>
+class ObserverListPerfTest : public ::testing::Test {
+ public:
+ using ObserverListType = typename Pick<ObserverType>::ObserverListType;
+
+ ObserverListPerfTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ObserverListPerfTest);
+};
+
+typedef ::testing::Types<UnsafeObserver, TestCheckedObserver> ObserverTypes;
+TYPED_TEST_CASE(ObserverListPerfTest, ObserverTypes);
+
+// Performance test for base::ObserverList and Checked Observers.
+TYPED_TEST(ObserverListPerfTest, NotifyPerformance) {
+ constexpr int kMaxObservers = 128;
+#if DCHECK_IS_ON()
+ // The test takes about 100x longer in debug builds, mostly due to sequence
+ // checker overheads when WeakPtr gets involved.
+ constexpr int kLaps = 1000000;
+#else
+ constexpr int kLaps = 100000000;
+#endif
+ constexpr int kWarmupLaps = 100;
+ std::vector<std::unique_ptr<TypeParam>> observers;
+
+ for (int observer_count = 0; observer_count <= kMaxObservers;
+ observer_count = observer_count ? observer_count * 2 : 1) {
+ typename TestFixture::ObserverListType list;
+ for (int i = 0; i < observer_count; ++i)
+ observers.push_back(std::make_unique<TypeParam>());
+ for (auto& o : observers)
+ list.AddObserver(o.get());
+
+ for (int i = 0; i < kWarmupLaps; ++i) {
+ for (auto& o : list)
+ o.Observe();
+ }
+ g_observer_list_perf_test_counter = 0;
+ const int weighted_laps = kLaps / (observer_count + 1);
+
+ TimeTicks start = TimeTicks::Now();
+ for (int i = 0; i < weighted_laps; ++i) {
+ for (auto& o : list)
+ o.Observe();
+ }
+ TimeDelta duration = TimeTicks::Now() - start;
+
+ const char* name = Pick<TypeParam>::GetName();
+ observers.clear();
+
+ EXPECT_EQ(observer_count * weighted_laps,
+ g_observer_list_perf_test_counter);
+ EXPECT_TRUE(observer_count == 0 || list.might_have_observers());
+
+ std::string prefix =
+ base::StringPrintf("ObserverListPerfTest_%d.", observer_count);
+
+ // A typical value is 3-20 nanoseconds per observe in Release, 1000-2000ns
+ // in an optimized build with DCHECKs and 3000-6000ns in debug builds.
+ perf_test::PrintResult(
+ prefix, name, "NotifyPerformance",
+ duration.InNanoseconds() /
+ static_cast<double>(g_observer_list_perf_test_counter +
+ weighted_laps),
+ "ns/observe", true);
+ }
+}
+
+} // namespace base