Skip to content

Commit 7c6f863

Browse files
pcloudsgitster
authored andcommitted
unpack-trees: reduce malloc in cache-tree walk
This is a micro optimization that probably only shines on repos with deep directory structure. Instead of allocating and freeing a new cache_entry in every iteration, we reuse the last one and only update the parts that are new each iteration. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 589bed1 commit 7c6f863

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

unpack-trees.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ static int traverse_by_cache_tree(int pos, int nr_entries, int nr_names,
694694
{
695695
struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
696696
struct unpack_trees_options *o = info->data;
697+
struct cache_entry *tree_ce = NULL;
698+
int ce_len = 0;
697699
int i, d;
698700

699701
if (!o->merge)
@@ -708,30 +710,39 @@ static int traverse_by_cache_tree(int pos, int nr_entries, int nr_names,
708710
* in the first place.
709711
*/
710712
for (i = 0; i < nr_entries; i++) {
711-
struct cache_entry *tree_ce;
712-
int len, rc;
713+
int new_ce_len, len, rc;
713714

714715
src[0] = o->src_index->cache[pos + i];
715716

716717
len = ce_namelen(src[0]);
717-
tree_ce = xcalloc(1, cache_entry_size(len));
718+
new_ce_len = cache_entry_size(len);
719+
720+
if (new_ce_len > ce_len) {
721+
new_ce_len <<= 1;
722+
tree_ce = xrealloc(tree_ce, new_ce_len);
723+
memset(tree_ce, 0, new_ce_len);
724+
ce_len = new_ce_len;
725+
726+
tree_ce->ce_flags = create_ce_flags(0);
727+
728+
for (d = 1; d <= nr_names; d++)
729+
src[d] = tree_ce;
730+
}
718731

719732
tree_ce->ce_mode = src[0]->ce_mode;
720-
tree_ce->ce_flags = create_ce_flags(0);
721733
tree_ce->ce_namelen = len;
722734
oidcpy(&tree_ce->oid, &src[0]->oid);
723735
memcpy(tree_ce->name, src[0]->name, len + 1);
724736

725-
for (d = 1; d <= nr_names; d++)
726-
src[d] = tree_ce;
727-
728737
rc = call_unpack_fn((const struct cache_entry * const *)src, o);
729-
free(tree_ce);
730-
if (rc < 0)
738+
if (rc < 0) {
739+
free(tree_ce);
731740
return rc;
741+
}
732742

733743
mark_ce_used(src[0], o);
734744
}
745+
free(tree_ce);
735746
if (o->debug_unpack)
736747
printf("Unpacked %d entries from %s to %s using cache-tree\n",
737748
nr_entries,

0 commit comments

Comments
 (0)