tree-diff: reuse base str(buf) memory on sub-tree recursion
Instead of allocating it all the time for every subtree in ll_diff_tree_sha1, let's allocate it once in diff_tree_sha1, and then all callee just use it in stacking style, without memory allocations. This should be faster, and for me this change gives the following slight speedups for git log --raw --no-abbrev --no-renames --format='%H' navy.git linux.git v3.10..v3.11 before 0.618s 1.903s after 0.611s 1.889s speedup 1.1% 0.7% Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Kirill Smelkov committed
Mar 27, 2014 at 18:22 UTC
12cd81743dc4645ef909b0c38582f5714c9a8ff7
1 file changed
+19
-19
tree-diff.c
+19
-19
@@ -8,7 +8,7 @@
8
9
10
static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
11
- const char *base_str, struct diff_options *opt);
11
+ struct strbuf *base, struct diff_options *opt);
12
13
/*
14
* Compare two tree entries, taking into account only path/S_ISDIR(mode),
@@ -123,7 +123,7 @@ static void show_path(struct strbuf *base, struct diff_options *opt,
123
if (recurse) {
124
strbuf_addch(base, '/');
125
ll_diff_tree_sha1(t1 ? t1->entry.sha1 : NULL,
126
- t2 ? t2->entry.sha1 : NULL, base->buf, opt);
126
+ t2 ? t2->entry.sha1 : NULL, base, opt);
127
}
128
129
strbuf_setlen(base, old_baselen);
@@ -146,12 +146,10 @@ static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
146
}
147
148
static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
149
- const char *base_str, struct diff_options *opt)
149
+ struct strbuf *base, struct diff_options *opt)
150
{
151
struct tree_desc t1, t2;
152
void *t1tree, *t2tree;
153
- struct strbuf base;
154
- int baselen = strlen(base_str);
153
154
t1tree = fill_tree_descriptor(&t1, old);
155
t2tree = fill_tree_descriptor(&t2, new);
@@ -159,17 +157,14 @@ static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
157
/* Enable recursion indefinitely */
158
opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
159
162
- strbuf_init(&base, PATH_MAX);
163
- strbuf_add(&base, base_str, baselen);
164
-
160
for (;;) {
161
int cmp;
162
163
if (diff_can_quit_early(opt))
164
break;
165
if (opt->pathspec.nr) {
171
- skip_uninteresting(&t1, &base, opt);
172
- skip_uninteresting(&t2, &base, opt);
166
+ skip_uninteresting(&t1, base, opt);
167
+ skip_uninteresting(&t2, base, opt);
168
}
169
if (!t1.size && !t2.size)
170
break;
@@ -181,7 +176,7 @@ static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
176
if (DIFF_OPT_TST(opt, FIND_COPIES_HARDER) ||
177
hashcmp(t1.entry.sha1, t2.entry.sha1) ||
178
(t1.entry.mode != t2.entry.mode))
184
- show_path(&base, opt, &t1, &t2);
179
+ show_path(base, opt, &t1, &t2);
180
181
update_tree_entry(&t1);
182
update_tree_entry(&t2);
@@ -189,18 +184,17 @@ static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
184
185
/* t1 < t2 */
186
else if (cmp < 0) {
192
- show_path(&base, opt, &t1, /*t2=*/NULL);
187
+ show_path(base, opt, &t1, /*t2=*/NULL);
188
update_tree_entry(&t1);
189
}
190
191
/* t1 > t2 */
192
else {
198
- show_path(&base, opt, /*t1=*/NULL, &t2);
193
+ show_path(base, opt, /*t1=*/NULL, &t2);
194
update_tree_entry(&t2);
195
}
196
}
197
203
- strbuf_release(&base);
198
free(t2tree);
199
free(t1tree);
200
return 0;
@@ -217,7 +211,7 @@ static inline int diff_might_be_rename(void)
211
!DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);
212
}
213
220
-static void try_to_follow_renames(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt)
214
+static void try_to_follow_renames(const unsigned char *old, const unsigned char *new, struct strbuf *base, struct diff_options *opt)
215
{
216
struct diff_options diff_opts;
217
struct diff_queue_struct *q = &diff_queued_diff;
@@ -314,13 +308,19 @@ static void try_to_follow_renames(const unsigned char *old, const unsigned char
308
q->nr = 1;
309
}
310
317
-int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt)
311
+int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base_str, struct diff_options *opt)
312
{
313
+ struct strbuf base;
314
int retval;
315
321
- retval = ll_diff_tree_sha1(old, new, base, opt);
322
- if (!*base && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename())
323
- try_to_follow_renames(old, new, base, opt);
316
+ strbuf_init(&base, PATH_MAX);
317
+ strbuf_addstr(&base, base_str);
318
+
319
+ retval = ll_diff_tree_sha1(old, new, &base, opt);
320
+ if (!*base_str && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename())
321
+ try_to_follow_renames(old, new, &base, opt);
322
+
323
+ strbuf_release(&base);
324
325
return retval;
326
}