Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: base/message_loop/message_pump_perftest.cc

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/message_loop/message_pump_mac.mm ('k') | base/message_loop/message_pump_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/bind.h"
6 #include "base/format_macros.h"
7 #include "base/memory/scoped_vector.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/synchronization/condition_variable.h"
10 #include "base/synchronization/lock.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread.h"
13 #include "base/time/time.h"
14 #include "build/build_config.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "testing/perf/perf_test.h"
17
18 #if defined(OS_ANDROID)
19 #include "base/android/java_handler_thread.h"
20 #endif
21
22 namespace base {
23
24 class ScheduleWorkTest : public testing::Test {
25 public:
26 ScheduleWorkTest() : counter_(0) {}
27
28 void Increment(uint64_t amount) { counter_ += amount; }
29
30 void Schedule(int index) {
31 base::TimeTicks start = base::TimeTicks::Now();
32 base::ThreadTicks thread_start;
33 if (ThreadTicks::IsSupported())
34 thread_start = base::ThreadTicks::Now();
35 base::TimeDelta minimum = base::TimeDelta::Max();
36 base::TimeDelta maximum = base::TimeDelta();
37 base::TimeTicks now, lastnow = start;
38 uint64_t schedule_calls = 0u;
39 do {
40 for (size_t i = 0; i < kBatchSize; ++i) {
41 target_message_loop()->ScheduleWork();
42 schedule_calls++;
43 }
44 now = base::TimeTicks::Now();
45 base::TimeDelta laptime = now - lastnow;
46 lastnow = now;
47 minimum = std::min(minimum, laptime);
48 maximum = std::max(maximum, laptime);
49 } while (now - start < base::TimeDelta::FromSeconds(kTargetTimeSec));
50
51 scheduling_times_[index] = now - start;
52 if (ThreadTicks::IsSupported())
53 scheduling_thread_times_[index] =
54 base::ThreadTicks::Now() - thread_start;
55 min_batch_times_[index] = minimum;
56 max_batch_times_[index] = maximum;
57 target_message_loop()->PostTask(FROM_HERE,
58 base::Bind(&ScheduleWorkTest::Increment,
59 base::Unretained(this),
60 schedule_calls));
61 }
62
63 void ScheduleWork(MessageLoop::Type target_type, int num_scheduling_threads) {
64 #if defined(OS_ANDROID)
65 if (target_type == MessageLoop::TYPE_JAVA) {
66 java_thread_.reset(new android::JavaHandlerThread("target"));
67 java_thread_->Start();
68 } else
69 #endif
70 {
71 target_.reset(new Thread("target"));
72 target_->StartWithOptions(Thread::Options(target_type, 0u));
73 }
74
75 ScopedVector<Thread> scheduling_threads;
76 scheduling_times_.reset(new base::TimeDelta[num_scheduling_threads]);
77 scheduling_thread_times_.reset(new base::TimeDelta[num_scheduling_threads]);
78 min_batch_times_.reset(new base::TimeDelta[num_scheduling_threads]);
79 max_batch_times_.reset(new base::TimeDelta[num_scheduling_threads]);
80
81 for (int i = 0; i < num_scheduling_threads; ++i) {
82 scheduling_threads.push_back(new Thread("posting thread"));
83 scheduling_threads[i]->Start();
84 }
85
86 for (int i = 0; i < num_scheduling_threads; ++i) {
87 scheduling_threads[i]->message_loop()->PostTask(
88 FROM_HERE,
89 base::Bind(&ScheduleWorkTest::Schedule, base::Unretained(this), i));
90 }
91
92 for (int i = 0; i < num_scheduling_threads; ++i) {
93 scheduling_threads[i]->Stop();
94 }
95 #if defined(OS_ANDROID)
96 if (target_type == MessageLoop::TYPE_JAVA) {
97 java_thread_->Stop();
98 java_thread_.reset();
99 } else
100 #endif
101 {
102 target_->Stop();
103 target_.reset();
104 }
105 base::TimeDelta total_time;
106 base::TimeDelta total_thread_time;
107 base::TimeDelta min_batch_time = base::TimeDelta::Max();
108 base::TimeDelta max_batch_time = base::TimeDelta();
109 for (int i = 0; i < num_scheduling_threads; ++i) {
110 total_time += scheduling_times_[i];
111 total_thread_time += scheduling_thread_times_[i];
112 min_batch_time = std::min(min_batch_time, min_batch_times_[i]);
113 max_batch_time = std::max(max_batch_time, max_batch_times_[i]);
114 }
115 std::string trace = StringPrintf(
116 "%d_threads_scheduling_to_%s_pump",
117 num_scheduling_threads,
118 target_type == MessageLoop::TYPE_IO
119 ? "io"
120 : (target_type == MessageLoop::TYPE_UI ? "ui" : "default"));
121 perf_test::PrintResult(
122 "task",
123 "",
124 trace,
125 total_time.InMicroseconds() / static_cast<double>(counter_),
126 "us/task",
127 true);
128 perf_test::PrintResult(
129 "task",
130 "_min_batch_time",
131 trace,
132 min_batch_time.InMicroseconds() / static_cast<double>(kBatchSize),
133 "us/task",
134 false);
135 perf_test::PrintResult(
136 "task",
137 "_max_batch_time",
138 trace,
139 max_batch_time.InMicroseconds() / static_cast<double>(kBatchSize),
140 "us/task",
141 false);
142 if (ThreadTicks::IsSupported()) {
143 perf_test::PrintResult(
144 "task",
145 "_thread_time",
146 trace,
147 total_thread_time.InMicroseconds() / static_cast<double>(counter_),
148 "us/task",
149 true);
150 }
151 }
152
153 MessageLoop* target_message_loop() {
154 #if defined(OS_ANDROID)
155 if (java_thread_)
156 return java_thread_->message_loop();
157 #endif
158 return target_->message_loop();
159 }
160
161 private:
162 scoped_ptr<Thread> target_;
163 #if defined(OS_ANDROID)
164 scoped_ptr<android::JavaHandlerThread> java_thread_;
165 #endif
166 scoped_ptr<base::TimeDelta[]> scheduling_times_;
167 scoped_ptr<base::TimeDelta[]> scheduling_thread_times_;
168 scoped_ptr<base::TimeDelta[]> min_batch_times_;
169 scoped_ptr<base::TimeDelta[]> max_batch_times_;
170 uint64_t counter_;
171
172 static const size_t kTargetTimeSec = 5;
173 static const size_t kBatchSize = 1000;
174 };
175
176 TEST_F(ScheduleWorkTest, ThreadTimeToIOFromOneThread) {
177 ScheduleWork(MessageLoop::TYPE_IO, 1);
178 }
179
180 TEST_F(ScheduleWorkTest, ThreadTimeToIOFromTwoThreads) {
181 ScheduleWork(MessageLoop::TYPE_IO, 2);
182 }
183
184 TEST_F(ScheduleWorkTest, ThreadTimeToIOFromFourThreads) {
185 ScheduleWork(MessageLoop::TYPE_IO, 4);
186 }
187
188 TEST_F(ScheduleWorkTest, ThreadTimeToUIFromOneThread) {
189 ScheduleWork(MessageLoop::TYPE_UI, 1);
190 }
191
192 TEST_F(ScheduleWorkTest, ThreadTimeToUIFromTwoThreads) {
193 ScheduleWork(MessageLoop::TYPE_UI, 2);
194 }
195
196 TEST_F(ScheduleWorkTest, ThreadTimeToUIFromFourThreads) {
197 ScheduleWork(MessageLoop::TYPE_UI, 4);
198 }
199
200 TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromOneThread) {
201 ScheduleWork(MessageLoop::TYPE_DEFAULT, 1);
202 }
203
204 TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromTwoThreads) {
205 ScheduleWork(MessageLoop::TYPE_DEFAULT, 2);
206 }
207
208 TEST_F(ScheduleWorkTest, ThreadTimeToDefaultFromFourThreads) {
209 ScheduleWork(MessageLoop::TYPE_DEFAULT, 4);
210 }
211
212 #if defined(OS_ANDROID)
213 TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromOneThread) {
214 ScheduleWork(MessageLoop::TYPE_JAVA, 1);
215 }
216
217 TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromTwoThreads) {
218 ScheduleWork(MessageLoop::TYPE_JAVA, 2);
219 }
220
221 TEST_F(ScheduleWorkTest, ThreadTimeToJavaFromFourThreads) {
222 ScheduleWork(MessageLoop::TYPE_JAVA, 4);
223 }
224 #endif
225
226 class FakeMessagePump : public MessagePump {
227 public:
228 FakeMessagePump() {}
229 ~FakeMessagePump() override {}
230
231 void Run(Delegate* delegate) override {}
232
233 void Quit() override {}
234 void ScheduleWork() override {}
235 void ScheduleDelayedWork(const TimeTicks& delayed_work_time) override {}
236 };
237
238 class PostTaskTest : public testing::Test {
239 public:
240 void Run(int batch_size, int tasks_per_reload) {
241 base::TimeTicks start = base::TimeTicks::Now();
242 base::TimeTicks now;
243 MessageLoop loop(scoped_ptr<MessagePump>(new FakeMessagePump));
244 scoped_refptr<internal::IncomingTaskQueue> queue(
245 new internal::IncomingTaskQueue(&loop));
246 uint32_t num_posted = 0;
247 do {
248 for (int i = 0; i < batch_size; ++i) {
249 for (int j = 0; j < tasks_per_reload; ++j) {
250 queue->AddToIncomingQueue(
251 FROM_HERE, base::Bind(&DoNothing), base::TimeDelta(), false);
252 num_posted++;
253 }
254 TaskQueue loop_local_queue;
255 queue->ReloadWorkQueue(&loop_local_queue);
256 while (!loop_local_queue.empty()) {
257 PendingTask t = loop_local_queue.front();
258 loop_local_queue.pop();
259 loop.RunTask(t);
260 }
261 }
262
263 now = base::TimeTicks::Now();
264 } while (now - start < base::TimeDelta::FromSeconds(5));
265 std::string trace = StringPrintf("%d_tasks_per_reload", tasks_per_reload);
266 perf_test::PrintResult(
267 "task",
268 "",
269 trace,
270 (now - start).InMicroseconds() / static_cast<double>(num_posted),
271 "us/task",
272 true);
273 }
274 };
275
276 TEST_F(PostTaskTest, OneTaskPerReload) {
277 Run(10000, 1);
278 }
279
280 TEST_F(PostTaskTest, TenTasksPerReload) {
281 Run(10000, 10);
282 }
283
284 TEST_F(PostTaskTest, OneHundredTasksPerReload) {
285 Run(1000, 100);
286 }
287
288 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_pump_mac.mm ('k') | base/message_loop/message_pump_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698