[M73 Dev][Tizen] Fix compilation errors for TV profile
[platform/framework/web/chromium-efl.git] / base / observer_list_perftest.cc
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/observer_list.h"
6
7 #include <memory>
8
9 #include "base/logging.h"
10 #include "base/observer_list.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/time/time.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/perf/perf_test.h"
15
16 // Ask the compiler not to use a register for this counter, in case it decides
17 // to do magic optimizations like |counter += kLaps|.
18 volatile int g_observer_list_perf_test_counter;
19
20 namespace base {
21
22 class ObserverInterface {
23  public:
24   ObserverInterface() {}
25   virtual ~ObserverInterface() {}
26   virtual void Observe() const { ++g_observer_list_perf_test_counter; }
27
28  private:
29   DISALLOW_COPY_AND_ASSIGN(ObserverInterface);
30 };
31
32 class UnsafeObserver : public ObserverInterface {};
33
34 class TestCheckedObserver : public CheckedObserver, public ObserverInterface {};
35
36 template <class ObserverType>
37 struct Pick {
38   // The ObserverList type to use. Checked observers need to be in a checked
39   // ObserverList.
40   using ObserverListType = ObserverList<ObserverType>;
41   static const char* GetName() { return "CheckedObserver"; }
42 };
43 template <>
44 struct Pick<UnsafeObserver> {
45   using ObserverListType = ObserverList<ObserverInterface>::Unchecked;
46   static const char* GetName() { return "UnsafeObserver"; }
47 };
48
49 template <class ObserverType>
50 class ObserverListPerfTest : public ::testing::Test {
51  public:
52   using ObserverListType = typename Pick<ObserverType>::ObserverListType;
53
54   ObserverListPerfTest() {}
55
56  private:
57   DISALLOW_COPY_AND_ASSIGN(ObserverListPerfTest);
58 };
59
60 typedef ::testing::Types<UnsafeObserver, TestCheckedObserver> ObserverTypes;
61 TYPED_TEST_CASE(ObserverListPerfTest, ObserverTypes);
62
63 // Performance test for base::ObserverList and Checked Observers.
64 TYPED_TEST(ObserverListPerfTest, NotifyPerformance) {
65   constexpr int kMaxObservers = 128;
66 #if DCHECK_IS_ON()
67   // The test takes about 100x longer in debug builds, mostly due to sequence
68   // checker overheads when WeakPtr gets involved.
69   constexpr int kLaps = 1000000;
70 #else
71   constexpr int kLaps = 100000000;
72 #endif
73   constexpr int kWarmupLaps = 100;
74   std::vector<std::unique_ptr<TypeParam>> observers;
75
76   for (int observer_count = 0; observer_count <= kMaxObservers;
77        observer_count = observer_count ? observer_count * 2 : 1) {
78     typename TestFixture::ObserverListType list;
79     for (int i = 0; i < observer_count; ++i)
80       observers.push_back(std::make_unique<TypeParam>());
81     for (auto& o : observers)
82       list.AddObserver(o.get());
83
84     for (int i = 0; i < kWarmupLaps; ++i) {
85       for (auto& o : list)
86         o.Observe();
87     }
88     g_observer_list_perf_test_counter = 0;
89     const int weighted_laps = kLaps / (observer_count + 1);
90
91     TimeTicks start = TimeTicks::Now();
92     for (int i = 0; i < weighted_laps; ++i) {
93       for (auto& o : list)
94         o.Observe();
95     }
96     TimeDelta duration = TimeTicks::Now() - start;
97
98     const char* name = Pick<TypeParam>::GetName();
99     observers.clear();
100
101     EXPECT_EQ(observer_count * weighted_laps,
102               g_observer_list_perf_test_counter);
103     EXPECT_TRUE(observer_count == 0 || list.might_have_observers());
104
105     std::string prefix =
106         base::StringPrintf("ObserverListPerfTest_%d.", observer_count);
107
108     // A typical value is 3-20 nanoseconds per observe in Release, 1000-2000ns
109     // in an optimized build with DCHECKs and 3000-6000ns in debug builds.
110     perf_test::PrintResult(
111         prefix, name, "NotifyPerformance",
112         duration.InNanoseconds() /
113             static_cast<double>(g_observer_list_perf_test_counter +
114                                 weighted_laps),
115         "ns/observe", true);
116   }
117 }
118
119 }  // namespace base