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); |
