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

Side by Side Diff: base/trace_event/estimate_memory_usage_unittest.cc

Issue 2440393002: [tracing] Implement composable memory usage estimators. (Closed)
Patch Set: Rebase 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
« no previous file with comments | « base/trace_event/estimate_memory_usage.h ('k') | cc/resources/scoped_ui_resource.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 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 "base/trace_event/estimate_memory_usage.h"
6
7 #include <stdlib.h>
8
9 #include "base/memory/ptr_util.h"
10 #include "base/strings/string16.h"
11 #include "base/test/scoped_memory_usage.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 // Estimation accuracy (as percentage of the real usage).
15 #define ESTIMATION_ACCURACY 10
16
17 #define BEGIN_MEMORY_USAGE_SCOPE \
18 test::ScopedMemoryUsage scoped_memory_usage
19
20 #define EXPECT_MEMORY_USAGE(estimated_usage) \
21 { \
22 size_t real_usage = scoped_memory_usage.Usage(); \
23 bool estimation_is_accurate = IsAccurateEstimation( \
24 estimated_usage, \
25 real_usage, \
26 ESTIMATION_ACCURACY); \
27 EXPECT_TRUE(estimation_is_accurate) \
28 << estimated_usage << " is outside of " \
29 << ESTIMATION_ACCURACY << "% margin of " << real_usage; \
30 }
31
32 namespace base {
33 namespace trace_event {
34
35 namespace {
36
37 bool IsAccurateEstimation(size_t estimation, size_t reality, size_t margin) {
38 size_t low = reality - (reality * margin / 100);
39 size_t high = reality + (reality * margin / 100);
40 return estimation >= low && estimation <= high;
41 }
42
43 // Guaranteed (if at all possible) to hit short-string-optimization.
44 std::string GetShortString() {
45 // All known SSO implementations can accommodate 6-char strings.
46 return std::string("small");
47 }
48
49 // Guaranteed to defeat short-string-optimization and allocate on the heap.
50 std::string GetLongString(int seed = 0) {
51 // Definitely won't fit into std::string.
52 constexpr size_t kLongLength = sizeof(std::string) + 1;
53 std::string string(kLongLength, '?');
54 int random = seed;
55 for (auto& ch : string) {
56 random = random * 1103515245 + 12345;
57 ch = 'a' + abs(random % 26);
58 }
59 return string;
60 }
61
62 // Compilers will happily optimize allocation / deallocation
63 // completely if you don't use your pointer. This "uses" a
64 // pointer and prevents optimizations.
65 template <class T>
66 void UseAllocatedPointer(T* pointer) {
67 EXPECT_NE(1u, reinterpret_cast<uintptr_t>(pointer));
68 }
69
70 } // namespace
71
72 class EstimateMemoryUsageTest : public testing::Test {
73 public:
74 void SetUp() override { test::ScopedMemoryUsage::Initialize(); }
75 };
76
77 TEST_F(EstimateMemoryUsageTest, String) {
78 // Short
79 {
80 BEGIN_MEMORY_USAGE_SCOPE;
81 std::string string = GetShortString();
82 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(string));
83 }
84
85 // Long
86 {
87 BEGIN_MEMORY_USAGE_SCOPE;
88 std::string string = GetLongString();
89 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(string));
90 }
91
92 // Capacity
93 {
94 BEGIN_MEMORY_USAGE_SCOPE;
95 std::string string;
96 string.reserve(777);
97 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(string));
98 }
99 }
100
101 TEST_F(EstimateMemoryUsageTest, String16) {
102 auto copy16 = [](const std::string& source) -> string16 {
103 string16 copy(source.size(), '?');
104 std::copy(source.begin(), source.end(), copy.begin());
105 return copy;
106 };
107
108 // Short
109 {
110 BEGIN_MEMORY_USAGE_SCOPE;
111 string16 string = copy16(GetShortString());
112 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(string));
113 }
114
115 // Long
116 {
117 BEGIN_MEMORY_USAGE_SCOPE;
118 string16 string = copy16(GetLongString());
119 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(string));
120 }
121
122 // Capacity
123 {
124 BEGIN_MEMORY_USAGE_SCOPE;
125 string16 string;
126 string.reserve(777);
127 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(string));
128 }
129 }
130
131 TEST_F(EstimateMemoryUsageTest, Arrays) {
132 // std::array
133 {
134 BEGIN_MEMORY_USAGE_SCOPE;
135 std::array<std::string, 10> array{{GetLongString()}};
136 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(array));
137 }
138
139 // T[N]
140 {
141 BEGIN_MEMORY_USAGE_SCOPE;
142 struct Item {
143 std::unique_ptr<std::string> data;
144
145 Item() : data(new std::string(GetLongString())) {}
146 size_t EstimateMemoryUsage() const {
147 using base::trace_event::EstimateMemoryUsage;
148 return EstimateMemoryUsage(data);
149 }
150 };
151 Item array[10];
152 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(array));
153 }
154
155 // C array
156 {
157 BEGIN_MEMORY_USAGE_SCOPE;
158 struct Item {
159 char payload[10];
160 };
161 Item* array = new Item[7];
162 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(array, 7));
163 UseAllocatedPointer(array);
164 delete[] array;
165 }
166 }
167
168 TEST_F(EstimateMemoryUsageTest, UniquePtr) {
169 // Empty
170 {
171 BEGIN_MEMORY_USAGE_SCOPE;
172 std::unique_ptr<std::string> ptr;
173 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(ptr));
174 }
175
176 // Not empty
177 {
178 BEGIN_MEMORY_USAGE_SCOPE;
179 std::unique_ptr<std::string> ptr(new std::string(GetLongString()));
180 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(ptr));
181 }
182
183 // With a pointer
184 {
185 BEGIN_MEMORY_USAGE_SCOPE;
186 std::unique_ptr<std::string*> ptr(new std::string*());
187 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(ptr));
188 UseAllocatedPointer(ptr.get());
189 }
190
191 // With an array
192 {
193 BEGIN_MEMORY_USAGE_SCOPE;
194 struct Item {
195 int payload[10];
196 };
197 std::unique_ptr<Item[]> ptr(new Item[7]);
198 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(ptr, 7));
199 UseAllocatedPointer(ptr.get());
200 }
201 }
202
203 TEST_F(EstimateMemoryUsageTest, Vector) {
204 {
205 BEGIN_MEMORY_USAGE_SCOPE;
206 std::vector<std::string> vector;
207 for (int i = 0; i != 1000; ++i) {
208 vector.push_back(GetLongString(i));
209 }
210 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(vector));
211 }
212
213 // Capacity
214 {
215 BEGIN_MEMORY_USAGE_SCOPE;
216 struct POD {
217 short data;
218 };
219 std::vector<POD> vector;
220 vector.reserve(1000);
221 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(vector));
222 }
223 }
224
225 TEST_F(EstimateMemoryUsageTest, List) {
226 BEGIN_MEMORY_USAGE_SCOPE;
227 struct POD {
228 short data;
229 };
230 std::list<POD> list;
231 for (int i = 0; i != 1000; ++i) {
232 list.push_back(POD());
233 }
234 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(list));
235 }
236
237 TEST_F(EstimateMemoryUsageTest, Set) {
238 BEGIN_MEMORY_USAGE_SCOPE;
239 std::set<std::pair<int, std::string>> set;
240 for (int i = 0; i != 1000; ++i) {
241 set.insert({i, GetLongString(i)});
242 }
243 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(set));
244 }
245
246 TEST_F(EstimateMemoryUsageTest, MultiSet) {
247 BEGIN_MEMORY_USAGE_SCOPE;
248 std::multiset<bool> set;
249 for (int i = 0; i != 1000; ++i) {
250 set.insert((i & 1) != 0);
251 }
252 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(set));
253 }
254
255 TEST_F(EstimateMemoryUsageTest, Map) {
256 BEGIN_MEMORY_USAGE_SCOPE;
257 std::map<std::string, int> map;
258 for (int i = 0; i != 1000; ++i) {
259 map.insert({GetLongString(i), i});
260 }
261 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(map));
262 }
263
264 TEST_F(EstimateMemoryUsageTest, MultiMap) {
265 BEGIN_MEMORY_USAGE_SCOPE;
266 std::multimap<char, std::string> map;
267 for (int i = 0; i != 1000; ++i) {
268 map.insert({static_cast<char>(i), GetLongString(i)});
269 }
270 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(map));
271 }
272
273 TEST_F(EstimateMemoryUsageTest, UnorderedSet) {
274 BEGIN_MEMORY_USAGE_SCOPE;
275 std::unordered_set<std::string> set;
276 for (int i = 0; i != 1000; ++i) {
277 set.insert(GetLongString(i));
278 }
279 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(set));
280 }
281
282 TEST_F(EstimateMemoryUsageTest, UnorderedMultiSet) {
283 BEGIN_MEMORY_USAGE_SCOPE;
284 std::unordered_multiset<short> set;
285 for (int i = 0; i != 1000; ++i) {
286 set.insert(static_cast<short>(i));
287 }
288 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(set));
289 }
290
291 TEST_F(EstimateMemoryUsageTest, UnorderedMap) {
292 BEGIN_MEMORY_USAGE_SCOPE;
293 std::unordered_map<std::string, void*> map;
294 for (int i = 0; i != 1000; ++i) {
295 map.insert({GetLongString(i), reinterpret_cast<void*>(i)});
296 }
297 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(map));
298 }
299
300 TEST_F(EstimateMemoryUsageTest, UnorderedMultiMap) {
301 BEGIN_MEMORY_USAGE_SCOPE;
302 std::unordered_multimap<char, short> map;
303 for (int i = 0; i != 1000; ++i) {
304 map.insert({static_cast<char>(i), 777});
305 }
306 EXPECT_MEMORY_USAGE(EstimateMemoryUsage(map));
307 }
308
309 } // namespace trace_event
310 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/estimate_memory_usage.h ('k') | cc/resources/scoped_ui_resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698