mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:38:10 +00:00
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. :^)
This commit is contained in:
parent
8effe0b632
commit
058cd1241e
4 changed files with 37 additions and 4 deletions
|
@ -69,6 +69,7 @@ GUI::Model& Profile::model()
|
||||||
|
|
||||||
void Profile::rebuild_tree()
|
void Profile::rebuild_tree()
|
||||||
{
|
{
|
||||||
|
u32 filtered_event_count = 0;
|
||||||
Vector<NonnullRefPtr<ProfileNode>> roots;
|
Vector<NonnullRefPtr<ProfileNode>> roots;
|
||||||
|
|
||||||
auto find_or_create_root = [&roots](const String& symbol, u32 address, u32 offset, u64 timestamp) -> ProfileNode& {
|
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();
|
node->increment_self_count();
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
++filtered_event_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_profile_nodes(roots);
|
sort_profile_nodes(roots);
|
||||||
|
|
||||||
|
m_filtered_event_count = filtered_event_count;
|
||||||
m_roots = move(roots);
|
m_roots = move(roots);
|
||||||
m_model->update();
|
m_model->update();
|
||||||
}
|
}
|
||||||
|
@ -276,3 +280,10 @@ void Profile::set_inverted(bool inverted)
|
||||||
m_inverted = inverted;
|
m_inverted = inverted;
|
||||||
rebuild_tree();
|
rebuild_tree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Profile::set_show_percentages(bool show_percentages)
|
||||||
|
{
|
||||||
|
if (m_show_percentages == show_percentages)
|
||||||
|
return;
|
||||||
|
m_show_percentages = show_percentages;
|
||||||
|
}
|
||||||
|
|
|
@ -126,6 +126,8 @@ public:
|
||||||
Vector<Frame> frames;
|
Vector<Frame> frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u32 filtered_event_count() const { return m_filtered_event_count; }
|
||||||
|
|
||||||
const Vector<Event>& events() const { return m_events; }
|
const Vector<Event>& events() const { return m_events; }
|
||||||
|
|
||||||
u64 length_in_ms() const { return m_last_timestamp - m_first_timestamp; }
|
u64 length_in_ms() const { return m_last_timestamp - m_first_timestamp; }
|
||||||
|
@ -140,6 +142,9 @@ public:
|
||||||
bool is_inverted() const { return m_inverted; }
|
bool is_inverted() const { return m_inverted; }
|
||||||
void set_inverted(bool);
|
void set_inverted(bool);
|
||||||
|
|
||||||
|
bool show_percentages() const { return m_show_percentages; }
|
||||||
|
void set_show_percentages(bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Profile(Vector<Event>);
|
explicit Profile(Vector<Event>);
|
||||||
|
|
||||||
|
@ -147,6 +152,7 @@ private:
|
||||||
|
|
||||||
RefPtr<ProfileModel> m_model;
|
RefPtr<ProfileModel> m_model;
|
||||||
Vector<NonnullRefPtr<ProfileNode>> m_roots;
|
Vector<NonnullRefPtr<ProfileNode>> m_roots;
|
||||||
|
u32 m_filtered_event_count { 0 };
|
||||||
u64 m_first_timestamp { 0 };
|
u64 m_first_timestamp { 0 };
|
||||||
u64 m_last_timestamp { 0 };
|
u64 m_last_timestamp { 0 };
|
||||||
|
|
||||||
|
@ -158,4 +164,5 @@ private:
|
||||||
|
|
||||||
u32 m_deepest_stack_depth { 0 };
|
u32 m_deepest_stack_depth { 0 };
|
||||||
bool m_inverted { false };
|
bool m_inverted { false };
|
||||||
|
bool m_show_percentages { false };
|
||||||
};
|
};
|
||||||
|
|
|
@ -97,9 +97,9 @@ String ProfileModel::column_name(int column) const
|
||||||
{
|
{
|
||||||
switch (column) {
|
switch (column) {
|
||||||
case Column::SampleCount:
|
case Column::SampleCount:
|
||||||
return "# Samples";
|
return m_profile.show_percentages() ? "% Samples" : "# Samples";
|
||||||
case Column::SelfCount:
|
case Column::SelfCount:
|
||||||
return "# Self";
|
return m_profile.show_percentages() ? "% Self" : "# Self";
|
||||||
case Column::StackFrame:
|
case Column::StackFrame:
|
||||||
return "Stack Frame";
|
return "Stack Frame";
|
||||||
default:
|
default:
|
||||||
|
@ -127,10 +127,16 @@ GUI::Variant ProfileModel::data(const GUI::ModelIndex& index, Role role) const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (role == Role::Display) {
|
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();
|
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();
|
return node->self_count();
|
||||||
|
}
|
||||||
if (index.column() == Column::StackFrame)
|
if (index.column() == Column::StackFrame)
|
||||||
return node->symbol();
|
return node->symbol();
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -84,6 +84,15 @@ int main(int argc, char** argv)
|
||||||
invert_action->set_checked(false);
|
invert_action->set_checked(false);
|
||||||
view_menu->add_action(invert_action);
|
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));
|
menubar->add_menu(move(view_menu));
|
||||||
|
|
||||||
app.set_menubar(move(menubar));
|
app.set_menubar(move(menubar));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue