diff options
author | Erick Reyes <erickreyes@google.com> | 2019-02-28 18:22:24 -0800 |
---|---|---|
committer | Erick Reyes <erickreyes@google.com> | 2019-03-01 16:17:20 -0800 |
commit | 5a744684c3feab43f47721916d339b9111b1fd88 (patch) | |
tree | b7e1cb9dce18c3f156b5cd227aba56f6a09fe949 /libmeminfo | |
parent | 949a561cfaf96840101901c6c9448dd3e859a4bd (diff) | |
download | system_core-5a744684c3feab43f47721916d339b9111b1fd88.tar.gz system_core-5a744684c3feab43f47721916d339b9111b1fd88.tar.bz2 system_core-5a744684c3feab43f47721916d339b9111b1fd88.zip |
libmeminfo: librank optimization using maps instead of vectors
librank was calling std::vector::find_if in nested loops when iterating
through processes and maps.
Changed the implementation to use std::map::insert, this resulted in
a significant improvement to execution speed.
Test: time librank on crosshatch
Before: 1m22.57s real 1m15.87s user 0m05.79s system
After: 0m03.85s real 0m00.88s user 0m02.92s system
Bug: 124523194
Change-Id: I2b519d0bfd7f7929c6c4c6c2374794cb1a744585
Signed-off-by: Erick Reyes <erickreyes@google.com>
Diffstat (limited to 'libmeminfo')
-rw-r--r-- | libmeminfo/tools/librank.cpp | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/libmeminfo/tools/librank.cpp b/libmeminfo/tools/librank.cpp index 2c2583d15..e53c74610 100644 --- a/libmeminfo/tools/librank.cpp +++ b/libmeminfo/tools/librank.cpp @@ -26,6 +26,7 @@ #include <unistd.h> #include <algorithm> +#include <map> #include <memory> #include <vector> @@ -122,30 +123,22 @@ struct LibRecord { const std::string& name() const { return name_; } const MemUsage& usage() const { return usage_; } - const std::vector<ProcessRecord>& processes() const { return procs_; } + const std::map<pid_t, ProcessRecord>& processes() const { return procs_; } uint64_t pss() const { return usage_.pss; } void AddUsage(const ProcessRecord& proc, const MemUsage& mem_usage) { - auto process = std::find_if(procs_.begin(), procs_.end(), - [&](auto p) -> bool { return p.pid() == proc.pid(); }); - if (process == procs_.end()) { - process = procs_.emplace(procs_.end(), proc.pid()); - } - process->AddUsage(mem_usage); + auto [it, inserted] = procs_.insert(std::pair<pid_t, ProcessRecord>(proc.pid(), proc)); + it->second.AddUsage(mem_usage); add_mem_usage(&usage_, mem_usage); } - void Sort(std::function<bool(const ProcessRecord&, const ProcessRecord&)>& sorter) { - std::sort(procs_.begin(), procs_.end(), sorter); - } - private: std::string name_; MemUsage usage_; - std::vector<ProcessRecord> procs_; + std::map<pid_t, ProcessRecord> procs_; }; // List of every library / map -static std::vector<LibRecord> g_libs; +static std::map<std::string, LibRecord> g_libs; // List of library/map names that we don't want to show by default static const std::vector<std::string> g_blacklisted_libs = {"[heap]", "[stack]"}; @@ -204,13 +197,10 @@ static bool scan_libs_per_process(pid_t pid) { continue; } - auto lib = std::find_if(g_libs.begin(), g_libs.end(), - [&](auto l) -> bool { return map.name == l.name(); }); - if (lib == g_libs.end()) { - lib = g_libs.emplace(g_libs.end(), map.name); - } + auto [it, inserted] = + g_libs.insert(std::pair<std::string, LibRecord>(map.name, LibRecord(map.name))); + it->second.AddUsage(proc, map.usage); - lib->AddUsage(proc, map.usage); if (!g_has_swap && map.usage.swap) { g_has_swap = true; } @@ -321,11 +311,16 @@ int main(int argc, char* argv[]) { } printf("Name/PID\n"); + std::vector<LibRecord> v_libs; + v_libs.reserve(g_libs.size()); + std::transform(g_libs.begin(), g_libs.end(), std::back_inserter(v_libs), + [] (std::pair<std::string, LibRecord> const& pair) { return pair.second; }); + // sort the libraries by their pss - std::sort(g_libs.begin(), g_libs.end(), + std::sort(v_libs.begin(), v_libs.end(), [](const LibRecord& l1, const LibRecord& l2) { return l1.pss() > l2.pss(); }); - for (auto& lib : g_libs) { + for (auto& lib : v_libs) { printf("%6" PRIu64 "K %7s %6s %6s %6s ", lib.pss() / 1024, "", "", "", ""); if (g_has_swap) { printf(" %6s ", ""); @@ -333,9 +328,15 @@ int main(int argc, char* argv[]) { printf("%s\n", lib.name().c_str()); // sort all mappings first - lib.Sort(sort_func); - for (auto& p : lib.processes()) { + std::vector<ProcessRecord> procs; + procs.reserve(lib.processes().size()); + std::transform(lib.processes().begin(), lib.processes().end(), std::back_inserter(procs), + [] (std::pair<pid_t, ProcessRecord> const& pair) { return pair.second; }); + + std::sort(procs.begin(), procs.end(), sort_func); + + for (auto& p : procs) { const MemUsage& usage = p.usage(); printf(" %6s %7" PRIu64 "K %6" PRIu64 "K %6" PRIu64 "K %6" PRIu64 "K ", "", usage.vss / 1024, usage.rss / 1024, usage.pss / 1024, usage.uss / 1024); |