diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-10 16:19:40 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-10 16:01:50 +0000 |
commit | 51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch) | |
tree | 835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/base/observer_list_perftest.cc | |
parent | 6036726eb981b6c4b42047513b9d3f4ac865daac (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.cc | 119 |
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 |