From 058cd1241ec497911947266ef7e8f11d8bf8e5c7 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 2 Mar 2020 21:56:03 +0100 Subject: [PATCH] ProfileViewer: Add mode that shows percentages instead of sample counts Sometimes it's much nicer to work with percentages than raw sample counts when browsing through a profile. :^) --- DevTools/ProfileViewer/Profile.cpp | 11 +++++++++++ DevTools/ProfileViewer/Profile.h | 7 +++++++ DevTools/ProfileViewer/ProfileModel.cpp | 14 ++++++++++---- DevTools/ProfileViewer/main.cpp | 9 +++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/DevTools/ProfileViewer/Profile.cpp b/DevTools/ProfileViewer/Profile.cpp index 07071ecc94..e4984b7bab 100644 --- a/DevTools/ProfileViewer/Profile.cpp +++ b/DevTools/ProfileViewer/Profile.cpp @@ -69,6 +69,7 @@ GUI::Model& Profile::model() void Profile::rebuild_tree() { + u32 filtered_event_count = 0; Vector> roots; auto find_or_create_root = [&roots](const String& symbol, u32 address, u32 offset, u64 timestamp) -> ProfileNode& { @@ -146,10 +147,13 @@ void Profile::rebuild_tree() node->increment_self_count(); return IterationDecision::Continue; }); + + ++filtered_event_count; } sort_profile_nodes(roots); + m_filtered_event_count = filtered_event_count; m_roots = move(roots); m_model->update(); } @@ -276,3 +280,10 @@ void Profile::set_inverted(bool inverted) m_inverted = inverted; rebuild_tree(); } + +void Profile::set_show_percentages(bool show_percentages) +{ + if (m_show_percentages == show_percentages) + return; + m_show_percentages = show_percentages; +} diff --git a/DevTools/ProfileViewer/Profile.h b/DevTools/ProfileViewer/Profile.h index 8d7933c5e0..3c509f463c 100644 --- a/DevTools/ProfileViewer/Profile.h +++ b/DevTools/ProfileViewer/Profile.h @@ -126,6 +126,8 @@ public: Vector frames; }; + u32 filtered_event_count() const { return m_filtered_event_count; } + const Vector& events() const { return m_events; } u64 length_in_ms() const { return m_last_timestamp - m_first_timestamp; } @@ -140,6 +142,9 @@ public: bool is_inverted() const { return m_inverted; } void set_inverted(bool); + bool show_percentages() const { return m_show_percentages; } + void set_show_percentages(bool); + private: explicit Profile(Vector); @@ -147,6 +152,7 @@ private: RefPtr m_model; Vector> m_roots; + u32 m_filtered_event_count { 0 }; u64 m_first_timestamp { 0 }; u64 m_last_timestamp { 0 }; @@ -158,4 +164,5 @@ private: u32 m_deepest_stack_depth { 0 }; bool m_inverted { false }; + bool m_show_percentages { false }; }; diff --git a/DevTools/ProfileViewer/ProfileModel.cpp b/DevTools/ProfileViewer/ProfileModel.cpp index c9f78a23b8..5c7dd56112 100644 --- a/DevTools/ProfileViewer/ProfileModel.cpp +++ b/DevTools/ProfileViewer/ProfileModel.cpp @@ -97,9 +97,9 @@ String ProfileModel::column_name(int column) const { switch (column) { case Column::SampleCount: - return "# Samples"; + return m_profile.show_percentages() ? "% Samples" : "# Samples"; case Column::SelfCount: - return "# Self"; + return m_profile.show_percentages() ? "% Self" : "# Self"; case Column::StackFrame: return "Stack Frame"; default: @@ -127,10 +127,16 @@ GUI::Variant ProfileModel::data(const GUI::ModelIndex& index, Role role) const return {}; } if (role == Role::Display) { - if (index.column() == Column::SampleCount) + if (index.column() == Column::SampleCount) { + if (m_profile.show_percentages()) + return ((float)node->event_count() / (float)m_profile.filtered_event_count()) * 100.0f; return node->event_count(); - if (index.column() == Column::SelfCount) + } + if (index.column() == Column::SelfCount) { + if (m_profile.show_percentages()) + return ((float)node->self_count() / (float)m_profile.filtered_event_count()) * 100.0f; return node->self_count(); + } if (index.column() == Column::StackFrame) return node->symbol(); return {}; diff --git a/DevTools/ProfileViewer/main.cpp b/DevTools/ProfileViewer/main.cpp index d7f6f46f00..e0716976e3 100644 --- a/DevTools/ProfileViewer/main.cpp +++ b/DevTools/ProfileViewer/main.cpp @@ -84,6 +84,15 @@ int main(int argc, char** argv) invert_action->set_checked(false); view_menu->add_action(invert_action); + auto percent_action = GUI::Action::create("Show percentages", { Mod_Ctrl, Key_P }, [&](auto& action) { + action.set_checked(!action.is_checked()); + profile->set_show_percentages(action.is_checked()); + tree_view->update(); + }); + percent_action->set_checkable(true); + percent_action->set_checked(false); + view_menu->add_action(percent_action); + menubar->add_menu(move(view_menu)); app.set_menubar(move(menubar));