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

Side by Side Diff: components/omnibox/browser/history_quick_provider_performance_unittest.cc

Issue 2300323003: Adding performance tests for HQP that represent importance of optimising HistoryItemsForTerms method (Closed)
Patch Set: Rebasing on prepared components perftests. Created 4 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2016 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 "components/omnibox/browser/history_quick_provider.h"
6
7 #include <memory>
8 #include <string>
9
10 #include "base/macros.h"
11 #include "base/run_loop.h"
12 #include "base/scoped_observer.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "components/history/core/browser/history_backend.h"
15 #include "components/history/core/browser/history_database.h"
16 #include "components/history/core/browser/history_service.h"
17 #include "components/history/core/test/history_service_test_util.h"
18 #include "components/omnibox/browser/fake_autocomplete_provider_client.h"
19 #include "components/omnibox/browser/history_test_util.h"
20 #include "components/omnibox/browser/in_memory_url_index_test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "testing/perf/perf_test.h"
23
24 using base::ASCIIToUTF16;
Peter Kasting 2016/10/24 22:28:29 You don't use this symbol.
dyaroshev 2016/10/25 18:11:34 Done.
25 using base::Time;
26 using base::TimeDelta;
Peter Kasting 2016/10/24 22:28:29 Nit: Half the time this file explicitly qualifies
dyaroshev 2016/10/25 18:11:35 Done.
27
28 namespace history {
29
30 namespace {
31
32 constexpr std::size_t kSimilarUrlCount = 10000;
Peter Kasting 2016/10/24 22:28:29 Nit: For better or worse, we don't std::-qualify s
dyaroshev 2016/10/25 18:11:34 Done.
33 constexpr std::size_t kTestGroupSize = 5;
34
35 struct TestURLInfo {
36 std::string url;
37 std::string title;
38 int visit_count;
39 int typed_count;
40 int days_from_now;
41 };
42
43 std::string GenerateSymbolsToChooseFrom() {
44 std::string res;
45 auto append_chars = [&res](char from, char to) {
46 for (char ch = from; ch <= to; ++ch)
47 res += ch;
48 };
49 append_chars('a', 'z');
50 append_chars('A', 'Z');
51 append_chars('0', '9');
52 res += ",/=+?#";
53 return res;
54 }
55
56 std::string GenerateWeiredShortString(int seed) {
Peter Kasting 2016/10/24 22:28:28 Nit: Weird (But I don't love "weird" in a functio
dyaroshev 2016/10/25 18:11:35 Done.
57 CR_DEFINE_STATIC_LOCAL(std::string, syms, (GenerateSymbolsToChooseFrom()));
Peter Kasting 2016/10/24 22:28:29 Why not just: static constexpr char kSyms[] =
dyaroshev 2016/10/25 18:11:35 Done.
58 std::string res;
59 // Much like translating into another calculation system.
60 for (auto i = std::hash<int>()(seed); i; i /= syms.size()) {
Peter Kasting 2016/10/24 22:28:29 Do you really need to hash? Or do you just want r
dyaroshev 2016/10/25 18:11:35 I want to get somewhat uniformly distributed deter
Peter Kasting 2016/10/25 18:27:56 Because <random> is still on the TBD list for Chro
dyaroshev 2016/10/26 22:29:12 Rewrote with <random>. Will this slow down this pa
61 res += syms[i % syms.size()];
62 }
63 return res;
64 }
65
66 std::string GeneratePopularUrlVariation(std::size_t seed) {
67 constexpr char kPopularUrl[] =
Peter Kasting 2016/10/24 22:28:28 Nit: static
dyaroshev 2016/10/25 18:11:35 Done.
68 "http://long.popular_url_with.many_variations/";
69 std::string res = kPopularUrl;
70
71 constexpr int kShortStringsCount = 5;
72 for (std::size_t i = seed; i < seed + kShortStringsCount; ++i)
73 res += GenerateWeiredShortString(i);
74
75 return res;
76 }
77
78 } // namespace
79
80 // This test is based on HistoryQuickProviderTest
Peter Kasting 2016/10/24 22:28:29 Nit: Based how? And why is this useful informatio
dyaroshev 2016/10/25 18:11:34 Done.
81 class HQPPerfTestBase : public testing::Test {
82 public:
83 HQPPerfTestBase() = default;
84
85 protected:
86 void SetUp() override;
87 void TearDown() override;
88
89 void PrepareData(std::size_t data_count);
Peter Kasting 2016/10/24 22:28:28 Nit: Add comments on these functions about what th
Peter Kasting 2016/10/27 00:59:38 Still need this
dyaroshev 2016/10/27 06:09:21 Done.
90
91 base::TimeDelta RunTest(const base::string16& text);
92
93 void PrintMeasurements(const std::string& trace_name,
94 const std::vector<base::TimeDelta>& measurements);
95
96 history::HistoryBackend* history_backend() {
97 return client_->GetHistoryService()->history_backend_.get();
98 }
99
100 private:
101 void FillData(std::size_t data_count);
102
103 // Customisation point to data generation,
dyaroshev 2016/10/24 17:07:08 Customisation point for data generation.
104 virtual TestURLInfo GenerateNextUrlInfo() = 0;
105
106 base::MessageLoop message_loop_;
107 std::unique_ptr<FakeAutocompleteProviderClient> client_;
108
109 ACMatches ac_matches_; // The resulting matches after running RunTest.
110
111 scoped_refptr<HistoryQuickProvider> provider_;
112 };
Peter Kasting 2016/10/24 22:28:28 Nit: DISALLOW_COPY_AND_ASSIGN
dyaroshev 2016/10/25 18:11:35 Doesn't work for test classes. I get compilation e
Peter Kasting 2016/10/25 18:27:56 Oh? https://cs.chromium.org/chromium/src/base/bin
dyaroshev 2016/10/26 22:29:13 I forgot semicolon after DISALLOW_COPY_AND_ASSIGN.
113
114 void HQPPerfTestBase::SetUp() {
115 if (base::ThreadTicks::IsSupported())
116 base::ThreadTicks::WaitUntilInitialized();
117 client_.reset(new FakeAutocompleteProviderClient());
118 ASSERT_TRUE(client_->GetHistoryService());
119 }
120
121 void HQPPerfTestBase::TearDown() {
122 provider_ = nullptr;
123 // The InMemoryURLIndex must be explicitly shut down or it will DCHECK() in
124 // its destructor.
125 client_->GetInMemoryURLIndex()->Shutdown();
126 client_->set_in_memory_url_index(nullptr);
127 // History index rebuild task is created from main thread during SetUp,
128 // performed on DB thread and must be deleted on main thread.
129 // Run main loop to process delete task, to prevent leaks.
130 base::RunLoop().RunUntilIdle();
131 }
132
133 void HQPPerfTestBase::PrepareData(std::size_t data_count) {
134 FillData(data_count);
135
136 // |FillData()| must be called before |RebuildFromHistory()|. This will
137 // ensure that the index is properly populated with data from the database.
138 InMemoryURLIndex* url_index = client_->GetInMemoryURLIndex();
139 url_index->RebuildFromHistory(
140 client_->GetHistoryService()->history_backend_->db());
141 BlockUntilInMemoryURLIndexIsRefreshed(url_index);
142
143 // History index refresh creates rebuilt tasks to run on history thread.
144 // Block here to make sure that all of them are complete.
145 history::BlockUntilHistoryProcessesPendingRequests(
146 client_->GetHistoryService());
147
148 provider_ = new HistoryQuickProvider(client_.get());
149 }
150
151 void HQPPerfTestBase::FillData(std::size_t data_count) {
152 sql::Connection& db(history_backend()->db()->GetDB());
153 ASSERT_TRUE(db.is_open());
154
155 size_t visit_id = 1;
156 for (size_t i = 0; i < data_count; ++i) {
157 TestURLInfo cur = GenerateNextUrlInfo();
158 Time visit_time = Time::Now() - TimeDelta::FromDays(cur.days_from_now);
159 AddURLToDBForTests(&db, i + 1, cur.url, cur.title, cur.visit_count,
160 cur.typed_count, visit_time);
Peter Kasting 2016/10/24 22:28:28 Nit: Basically this whole loop body is also in his
dyaroshev 2016/10/25 18:11:35 Done.
161
162 auto add_visit = [&db, &visit_id, &visit_time,
163 &i](ui::PageTransition transtition) mutable {
164 // Assume earlier visits are at one-day intervals.
165 visit_time -= TimeDelta::FromDays(1);
166 history::AddVisitToDBForTests(&db, visit_id++, i + 1, visit_time,
167 transtition);
168 };
169
170 // Mark the most recent |cur.typed_count| visits as typed.
171 for (int j = 0; j < cur.typed_count; ++j)
172 add_visit(ui::PAGE_TRANSITION_TYPED);
173
174 for (int j = cur.typed_count; j < cur.visit_count; ++j)
175 add_visit(ui::PAGE_TRANSITION_LINK);
176 }
177 }
178
179 void HQPPerfTestBase::PrintMeasurements(
180 const std::string& trace_name,
181 const std::vector<base::TimeDelta>& measurements) {
182 auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
183
184 std::string durations;
185 for (const auto& measurement : measurements)
186 durations += std::to_string(measurement.InMillisecondsRoundedUp()) + ',';
187
188 perf_test::PrintResultList(test_info->test_case_name(), test_info->name(),
189 trace_name, durations, "ms", true);
190 }
191
192 base::TimeDelta HQPPerfTestBase::RunTest(const base::string16& text) {
193 base::RunLoop().RunUntilIdle();
194 AutocompleteInput input(text, base::string16::npos, std::string(), GURL(),
195 metrics::OmniboxEventProto::INVALID_SPEC, false,
196 false, true, true, false, TestSchemeClassifier());
197
198 base::Time regular_start = base::Time::Now();
199 base::ThreadTicks thread_start;
200 if (base::ThreadTicks::IsSupported())
201 thread_start = base::ThreadTicks::Now();
202
203 provider_->Start(input, false);
204 EXPECT_TRUE(provider_->done());
205
206 if (base::ThreadTicks::IsSupported())
207 return base::ThreadTicks::Now() - thread_start;
208
209 return base::Time::Now() - regular_start;
Peter Kasting 2016/10/24 22:28:29 Nit: I think it would be clearer to do something l
dyaroshev 2016/10/25 18:11:35 Done.
210 }
211
212 class HQPPerfTestOnePopularURL : public HQPPerfTestBase {
Peter Kasting 2016/10/24 22:28:29 Nit: Do we really buy much by splitting this out i
dyaroshev 2016/10/25 18:11:34 Done.
213 public:
214 void SetUp() override {
215 HQPPerfTestBase::SetUp();
216 PrepareData(kSimilarUrlCount);
217 }
218
219 private:
220 TestURLInfo GenerateNextUrlInfo() final {
221 ++call_count_;
222 return {
223 GeneratePopularUrlVariation(call_count_),
224 "Page " + std::to_string(call_count_),
225 1,
226 1,
227 1,
228 };
229 }
230
231 int call_count_;
232 };
Peter Kasting 2016/10/24 22:28:29 Nit: DISALLOW_COPY_AND_ASSIGN
233
234 TEST_F(HQPPerfTestOnePopularURL, Typing) {
235 auto test_url = GeneratePopularUrlVariation(kSimilarUrlCount + 1);
236
237 auto url_position_to_string = [&test_url](std::string::iterator it) {
238 return std::to_string(it - test_url.begin());
239 };
240
241 std::vector<base::TimeDelta> measurements;
242 measurements.reserve(kTestGroupSize);
243
244 for (auto i = test_url.begin(); i != test_url.end();) {
245 auto group_start = i;
246 auto group_end = std::min(i + kTestGroupSize, test_url.end());
247
248 for (auto j = group_start; j != group_end; ++j)
249 measurements.push_back(RunTest(base::UTF8ToUTF16({test_url.begin(), j})));
Peter Kasting 2016/10/24 22:28:29 Nit: AFAICT, this line is the only thing that diff
dyaroshev 2016/10/25 18:11:34 Haven't got around to it yet. I thought about it w
Peter Kasting 2016/10/25 18:27:56 Write this as a template, and pass begin()/end() t
dyaroshev 2016/10/26 22:29:13 Rewrote with StringPiece. I think, looks nice.
250
251 auto trace_name = url_position_to_string(group_start) + '-' +
252 url_position_to_string(group_end);
253
254 PrintMeasurements(trace_name, measurements);
255 i = group_end;
256 measurements.clear();
257 }
258 }
259
260 TEST_F(HQPPerfTestOnePopularURL, Backspacing) {
261 auto test_url = GeneratePopularUrlVariation(kSimilarUrlCount + 1);
Peter Kasting 2016/10/24 22:28:29 Nit: I'd prefer to use "auto" a little less aggres
dyaroshev 2016/10/25 18:11:35 Done.
262
263 auto url_position_to_string = [&test_url](std::string::reverse_iterator it) {
Peter Kasting 2016/10/24 22:28:29 Nit: I don't know if we have a rule on this, but I
dyaroshev 2016/10/25 18:11:35 Haven't got around to it yet.
dyaroshev 2016/10/26 22:29:13 Done, if I haven't missed anything.
264 return std::to_string(it.base() - test_url.begin());
265 };
266
267 std::vector<base::TimeDelta> measurements;
268 measurements.reserve(test_url.length());
269
270 for (auto i = test_url.rbegin(); i != test_url.rend();) {
Peter Kasting 2016/10/24 22:28:29 Nit: Place space between ; and ), unless this is h
dyaroshev 2016/10/25 18:11:35 clang-format
271 auto group_start = i;
272 auto group_end = std::min(i + kTestGroupSize, test_url.rend());
273
274 for (auto j = group_start; j != group_end; ++j)
Peter Kasting 2016/10/24 22:28:29 Nit: Why not just for (; i != group_end; ++i)
dyaroshev 2016/10/25 18:11:34 Haven't got around to it yet.
dyaroshev 2016/10/26 22:29:13 I've done smth cleaner than before.
275 measurements.push_back(
276 RunTest(base::UTF8ToUTF16({test_url.begin(), j.base()})));
277
278 auto trace_name = url_position_to_string(group_start) + '-' +
279 url_position_to_string(group_end);
Peter Kasting 2016/10/24 22:28:29 Nit: I'd probably just inline this into the next s
dyaroshev 2016/10/26 22:29:12 Done.
280
281 PrintMeasurements(trace_name, measurements);
282 i = group_end;
283 measurements.clear();
284 }
285 }
286
287 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698