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

Unified Diff: base/memory/memory_uma_perftest.cc

Issue 2865653003: One perf test for windows VirtualQueryEx calls.
Patch Set: add many test cases Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/memory/i_heart_windows_memory.cc ('k') | base/process/process_metrics.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/memory/memory_uma_perftest.cc
diff --git a/base/memory/memory_uma_perftest.cc b/base/memory/memory_uma_perftest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..587eb0fc7d69d5940863d4271b4a53abc2436e87
--- /dev/null
+++ b/base/memory/memory_uma_perftest.cc
@@ -0,0 +1,128 @@
+// Copyright 2017 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 <algorithm>
+
+#include "base/process/process_handle.h"
+#include "base/test/perf_time_logger.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+namespace {
+
+constexpr const int kNumRuns = 1000;
+constexpr const int kMaxRegions = 1000; // Runs of a single test seem to
+ // generate about 330 regions, so 1000
+ // should overkill.
+size_t memory_sizes[kNumRuns] = {};
+struct RunStat {
+ int num_regions;
+ TimeDelta* virtual_query_run_times;
+ TimeDelta run_time;
+} run_stats[kNumRuns];
+TimeDelta virtual_query_run_times_storage[kMaxRegions][kNumRuns];
+
+size_t GetPrivateMemoryFootprintWindows(ProcessHandle process,
+ const SYSTEM_INFO& system_info,
+ RunStat* run_stat) {
+ size_t private_memory_footprint = 0;
+ const char* current_address =
+ reinterpret_cast<const char*>(system_info.lpMinimumApplicationAddress);
+
+ TimeDelta* cur_run = &run_stat->virtual_query_run_times[0];
+ while (current_address <= system_info.lpMaximumApplicationAddress) {
+ MEMORY_BASIC_INFORMATION region;
+
+ TimeTicks start = TimeTicks::Now();
+ if (::VirtualQueryEx(process, current_address, &region, sizeof(region)) !=
+ 0) {
+ ++(run_stat->num_regions);
+ if (region.Type == MEM_PRIVATE && region.State == MEM_COMMIT) {
+ private_memory_footprint += region.RegionSize;
+ }
+ current_address =
+ reinterpret_cast<const char*>(region.BaseAddress) + region.RegionSize;
+ } else {
+ // This should not happen but if it does, just go to the next page and
+ // continue.
+ DPLOG(ERROR) << "Error calling VirtualQueryEx for process: " << process
+ << " and address: "
+ << reinterpret_cast<intptr_t>(current_address);
+
+ // TODO(ajwong): What happens if we overflow?
+ current_address += system_info.dwPageSize;
+ }
+ *(cur_run++) = TimeTicks::Now() - start;
+ }
+ return private_memory_footprint;
+}
+
+TEST(MemoryUma, CalculatePrivateMemory) {
+ ProcessHandle current_process = GetCurrentProcessHandle();
+ SYSTEM_INFO system_info;
+ ::GetSystemInfo(&system_info);
+
+ PerfTimeLogger timer("Memory_uma_private_memory");
+ for (int i = 0; i < kNumRuns; ++i) {
+ TimeTicks start = TimeTicks::Now();
+ run_stats[i].virtual_query_run_times = virtual_query_run_times_storage[i];
+ memory_sizes[i] = GetPrivateMemoryFootprintWindows(
+ current_process, system_info, &run_stats[i]);
+ run_stats[i].run_time = TimeTicks::Now() - start;
+ }
+ timer.Done();
+
+ std::sort(memory_sizes, memory_sizes + kNumRuns);
+ LOG(ERROR) << "Memory Smallest: " << memory_sizes[0];
+ LOG(ERROR) << "Memory 95% percentile: "
+ << memory_sizes[static_cast<int>(.95 * kNumRuns)];
+ LOG(ERROR) << "Memory Largest: " << memory_sizes[kNumRuns - 1] << std::endl;
+
+ std::sort(run_stats, run_stats + kNumRuns,
+ [](const RunStat& a, const RunStat& b) {
+ return a.num_regions < b.num_regions;
+ });
+ LOG(ERROR) << "Num Regions Smallest: " << run_stats[0].num_regions;
+ LOG(ERROR) << "Num Regions 95% percentile: "
+ << run_stats[static_cast<int>(.95 * kNumRuns)].num_regions;
+ LOG(ERROR) << "Num Regions Largest: " << run_stats[kNumRuns - 1].num_regions
+ << std::endl;
+
+ std::sort(run_stats, run_stats + kNumRuns,
+ [](const RunStat& a, const RunStat& b) {
+ return a.run_time < b.run_time;
+ });
+ LOG(ERROR) << "Run Time Smallest: "
+ << run_stats[0].run_time.InMillisecondsF();
+ LOG(ERROR)
+ << "Run Time 95% percentile: "
+ << run_stats[static_cast<int>(.95 * kNumRuns)].run_time.InMillisecondsF();
+ LOG(ERROR) << "Run Time Second Largest: "
+ << run_stats[kNumRuns - 2].run_time.InMillisecondsF();
+ const RunStat& longest = run_stats[kNumRuns - 1];
+ LOG(ERROR) << "Run Time Largest: " << longest.run_time.InMillisecondsF()
+ << std::endl;
+
+ std::sort(longest.virtual_query_run_times,
+ longest.virtual_query_run_times + kMaxRegions);
+ LOG(ERROR) << "[longest] VirtualQueryEx Run Time Smallest: "
+ << longest.virtual_query_run_times[0].InMillisecondsF();
+ LOG(ERROR) << "[longest] VirtualQueryEx Run Time 50% percentile: "
+ << longest.virtual_query_run_times[static_cast<int>(.5 * kNumRuns)]
+ .InMillisecondsF();
+ LOG(ERROR) << "[longest] VirtualQueryEx Run Time 95% percentile: "
+ << longest
+ .virtual_query_run_times[static_cast<int>(.95 * kNumRuns)]
+ .InMillisecondsF();
+ LOG(ERROR) << "[longest] VirtualQueryEx Run Time Second Largest: "
+ << longest.virtual_query_run_times[kNumRuns - 2].InMillisecondsF();
+ LOG(ERROR) << "[longest] VirtualQueryEx Run Time Largest: "
+ << longest.virtual_query_run_times[kNumRuns - 1].InMillisecondsF();
+}
+
+} // namespace
+
+} // namespace base
« no previous file with comments | « base/memory/i_heart_windows_memory.cc ('k') | base/process/process_metrics.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698