shortlog: optimize out useless string list
If we are in "--summary" mode, then we do not care about the actual list of subject onelines associated with each author. We care only about the number. So rather than store a string-list for each author full of "<none>", let's just keep a count. This drops my best-of-five for "git shortlog -ns HEAD" on linux.git from: real 0m5.194s user 0m5.028s sys 0m0.168s to: real 0m5.057s user 0m4.916s sys 0m0.144s That's about 2.5%. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
ed7eba9022
commit
9b21a34a96
@ -14,7 +14,26 @@ static char const * const shortlog_usage[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static int compare_by_number(const void *a1, const void *a2)
|
||||
/*
|
||||
* The util field of our string_list_items will contain one of two things:
|
||||
*
|
||||
* - if --summary is not in use, it will point to a string list of the
|
||||
* oneline subjects assigned to this author
|
||||
*
|
||||
* - if --summary is in use, we don't need that list; we only need to know
|
||||
* its size. So we abuse the pointer slot to store our integer counter.
|
||||
*
|
||||
* This macro accesses the latter.
|
||||
*/
|
||||
#define UTIL_TO_INT(x) ((intptr_t)(x)->util)
|
||||
|
||||
static int compare_by_counter(const void *a1, const void *a2)
|
||||
{
|
||||
const struct string_list_item *i1 = a1, *i2 = a2;
|
||||
return UTIL_TO_INT(i2) - UTIL_TO_INT(i1);
|
||||
}
|
||||
|
||||
static int compare_by_list(const void *a1, const void *a2)
|
||||
{
|
||||
const struct string_list_item *i1 = a1, *i2 = a2;
|
||||
const struct string_list *l1 = i1->util, *l2 = i2->util;
|
||||
@ -52,11 +71,9 @@ static void insert_one_record(struct shortlog *log,
|
||||
strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf);
|
||||
|
||||
item = string_list_insert(&log->list, namemailbuf.buf);
|
||||
if (item->util == NULL)
|
||||
item->util = xcalloc(1, sizeof(struct string_list));
|
||||
|
||||
if (log->summary)
|
||||
string_list_append(item->util, xstrdup(""));
|
||||
item->util = (void *)(UTIL_TO_INT(item) + 1);
|
||||
else {
|
||||
const char *dot3 = log->common_repo_prefix;
|
||||
char *buffer, *p;
|
||||
@ -90,6 +107,8 @@ static void insert_one_record(struct shortlog *log,
|
||||
}
|
||||
}
|
||||
|
||||
if (item->util == NULL)
|
||||
item->util = xcalloc(1, sizeof(struct string_list));
|
||||
string_list_append(item->util, buffer);
|
||||
}
|
||||
}
|
||||
@ -295,14 +314,14 @@ void shortlog_output(struct shortlog *log)
|
||||
|
||||
if (log->sort_by_number)
|
||||
qsort(log->list.items, log->list.nr, sizeof(struct string_list_item),
|
||||
compare_by_number);
|
||||
log->summary ? compare_by_counter : compare_by_list);
|
||||
for (i = 0; i < log->list.nr; i++) {
|
||||
struct string_list *onelines = log->list.items[i].util;
|
||||
|
||||
const struct string_list_item *item = &log->list.items[i];
|
||||
if (log->summary) {
|
||||
printf("%6d\t%s\n", onelines->nr, log->list.items[i].string);
|
||||
printf("%6d\t%s\n", (int)UTIL_TO_INT(item), item->string);
|
||||
} else {
|
||||
printf("%s (%d):\n", log->list.items[i].string, onelines->nr);
|
||||
struct string_list *onelines = item->util;
|
||||
printf("%s (%d):\n", item->string, onelines->nr);
|
||||
for (j = onelines->nr - 1; j >= 0; j--) {
|
||||
const char *msg = onelines->items[j].string;
|
||||
|
||||
@ -315,11 +334,11 @@ void shortlog_output(struct shortlog *log)
|
||||
printf(" %s\n", msg);
|
||||
}
|
||||
putchar('\n');
|
||||
onelines->strdup_strings = 1;
|
||||
string_list_clear(onelines, 0);
|
||||
free(onelines);
|
||||
}
|
||||
|
||||
onelines->strdup_strings = 1;
|
||||
string_list_clear(onelines, 0);
|
||||
free(onelines);
|
||||
log->list.items[i].util = NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user