diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-12-28 19:48:36 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-12-30 06:00:00 -0500 |
commit | 9c443dfdd31eddea6cbe6ee0ca469fbcc4e1dc3b (patch) | |
tree | 6e217aaf89b941fbbc7b905046d5350392d642db /tools/perf/builtin-diff.c | |
parent | cdbae31408cf39372402076cf2e189ec693daa71 (diff) |
perf diff: Fix support for all --sort combinations
When we finish creating the hist_entries we _already_ have them
sorted "by name", in fact by what is in --sort, that is exactly
how we can find the pairs in perf_session__match_hists as
'comm', 'dso' & 'symbol' all are strings we need to find the
matches in the baseline session.
So only do the sort by hits followed by a resort by --sort if we
need to find the position for shwowing the --displacement of
hist entries.
Now all these modes work correctly:
Example is a simple 'perf record -f find / > /dev/null' ran
twice then followed by the following commands:
$ perf diff -f --sort comm
# Baseline Delta Command
# ........ .......... .......
#
0.00% +100.00% find
$ perf diff -f --sort dso
# Baseline Delta Shared Object
# ........ .......... ..................
#
59.97% -0.44% [kernel]
21.17% +0.28% libc-2.5.so
18.49% +0.16% [ext3]
0.37% find
$ perf diff -f --sort symbol | head -8
# Baseline Delta Symbol
# ........ .......... ......
#
6.21% +0.36% [k] ext3fs_dirhash
3.43% +0.41% [.] __GI_strlen
3.53% +0.16% [k] __kmalloc
3.17% +0.49% [k] system_call
3.06% +0.37% [k] ext3_htree_store_dirent
$ perf diff -f --sort dso,symbol | head -8
# Baseline Delta Shared Object Symbol
# ........ .......... .................. ......
#
6.21% +0.36% [ext3] [k] ext3fs_dirhash
3.43% +0.41% libc-2.5.so [.] __GI_strlen
3.53% +0.16% [kernel] [k] __kmalloc
3.17% +0.49% [kernel] [k] system_call
3.06% +0.37% [ext3] [k] ext3_htree_store_dirent
$
And we don't have to do two expensive resorts in the common, non
--displacement case.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1262047716-23171-5-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r-- | tools/perf/builtin-diff.c | 52 |
1 files changed, 21 insertions, 31 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 876a4b981be8..924bfb77a6ab 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -82,29 +82,19 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root, | |||
82 | struct hist_entry *iter; | 82 | struct hist_entry *iter; |
83 | 83 | ||
84 | while (*p != NULL) { | 84 | while (*p != NULL) { |
85 | int cmp; | ||
86 | parent = *p; | 85 | parent = *p; |
87 | iter = rb_entry(parent, struct hist_entry, rb_node); | 86 | iter = rb_entry(parent, struct hist_entry, rb_node); |
88 | 87 | if (hist_entry__cmp(he, iter) < 0) | |
89 | cmp = strcmp(he->map->dso->name, iter->map->dso->name); | ||
90 | if (cmp > 0) | ||
91 | p = &(*p)->rb_left; | 88 | p = &(*p)->rb_left; |
92 | else if (cmp < 0) | 89 | else |
93 | p = &(*p)->rb_right; | 90 | p = &(*p)->rb_right; |
94 | else { | ||
95 | cmp = strcmp(he->sym->name, iter->sym->name); | ||
96 | if (cmp > 0) | ||
97 | p = &(*p)->rb_left; | ||
98 | else | ||
99 | p = &(*p)->rb_right; | ||
100 | } | ||
101 | } | 91 | } |
102 | 92 | ||
103 | rb_link_node(&he->rb_node, parent, p); | 93 | rb_link_node(&he->rb_node, parent, p); |
104 | rb_insert_color(&he->rb_node, root); | 94 | rb_insert_color(&he->rb_node, root); |
105 | } | 95 | } |
106 | 96 | ||
107 | static void perf_session__resort_by_name(struct perf_session *self) | 97 | static void perf_session__resort_hist_entries(struct perf_session *self) |
108 | { | 98 | { |
109 | unsigned long position = 1; | 99 | unsigned long position = 1; |
110 | struct rb_root tmp = RB_ROOT; | 100 | struct rb_root tmp = RB_ROOT; |
@@ -122,29 +112,28 @@ static void perf_session__resort_by_name(struct perf_session *self) | |||
122 | self->hists = tmp; | 112 | self->hists = tmp; |
123 | } | 113 | } |
124 | 114 | ||
115 | static void perf_session__set_hist_entries_positions(struct perf_session *self) | ||
116 | { | ||
117 | perf_session__output_resort(self, self->events_stats.total); | ||
118 | perf_session__resort_hist_entries(self); | ||
119 | } | ||
120 | |||
125 | static struct hist_entry * | 121 | static struct hist_entry * |
126 | perf_session__find_hist_entry_by_name(struct perf_session *self, | 122 | perf_session__find_hist_entry(struct perf_session *self, |
127 | struct hist_entry *he) | 123 | struct hist_entry *he) |
128 | { | 124 | { |
129 | struct rb_node *n = self->hists.rb_node; | 125 | struct rb_node *n = self->hists.rb_node; |
130 | 126 | ||
131 | while (n) { | 127 | while (n) { |
132 | struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); | 128 | struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); |
133 | int cmp = strcmp(he->map->dso->name, iter->map->dso->name); | 129 | int64_t cmp = hist_entry__cmp(he, iter); |
134 | 130 | ||
135 | if (cmp > 0) | 131 | if (cmp < 0) |
136 | n = n->rb_left; | 132 | n = n->rb_left; |
137 | else if (cmp < 0) | 133 | else if (cmp > 0) |
138 | n = n->rb_right; | 134 | n = n->rb_right; |
139 | else { | 135 | else |
140 | cmp = strcmp(he->sym->name, iter->sym->name); | 136 | return iter; |
141 | if (cmp > 0) | ||
142 | n = n->rb_left; | ||
143 | else if (cmp < 0) | ||
144 | n = n->rb_right; | ||
145 | else | ||
146 | return iter; | ||
147 | } | ||
148 | } | 137 | } |
149 | 138 | ||
150 | return NULL; | 139 | return NULL; |
@@ -155,11 +144,9 @@ static void perf_session__match_hists(struct perf_session *old_session, | |||
155 | { | 144 | { |
156 | struct rb_node *nd; | 145 | struct rb_node *nd; |
157 | 146 | ||
158 | perf_session__resort_by_name(old_session); | ||
159 | |||
160 | for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) { | 147 | for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) { |
161 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); | 148 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); |
162 | pos->pair = perf_session__find_hist_entry_by_name(old_session, pos); | 149 | pos->pair = perf_session__find_hist_entry(old_session, pos); |
163 | } | 150 | } |
164 | } | 151 | } |
165 | 152 | ||
@@ -177,9 +164,12 @@ static int __cmd_diff(void) | |||
177 | ret = perf_session__process_events(session[i], &event_ops); | 164 | ret = perf_session__process_events(session[i], &event_ops); |
178 | if (ret) | 165 | if (ret) |
179 | goto out_delete; | 166 | goto out_delete; |
180 | perf_session__output_resort(session[i], session[i]->events_stats.total); | ||
181 | } | 167 | } |
182 | 168 | ||
169 | perf_session__output_resort(session[1], session[1]->events_stats.total); | ||
170 | if (show_displacement) | ||
171 | perf_session__set_hist_entries_positions(session[0]); | ||
172 | |||
183 | perf_session__match_hists(session[0], session[1]); | 173 | perf_session__match_hists(session[0], session[1]); |
184 | perf_session__fprintf_hists(session[1], session[0], | 174 | perf_session__fprintf_hists(session[1], session[0], |
185 | show_displacement, stdout); | 175 | show_displacement, stdout); |