Preallocate hash tables when the number of inserts are known in advance

This avoids unnecessary re-allocations and reinsertions. On webkit.git (i.e. about 182k inserts to the name hash table), this reduces about 100ms out of 3s user time. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 17, 2013 at 10:28 UTC c73592812d36ccc7eccfd0489177970d246fa522
3 files changed +10
diffcore-rename.c
+1
@@ -389,6 +389,7 @@ static int find_exact_renames(struct diff_options *options)
389 struct hash_table file_table;
390
391 init_hash(&file_table);
392 + preallocate_hash(&file_table, rename_src_nr + rename_dst_nr);
393 for (i = 0; i < rename_src_nr; i++)
394 insert_file_table(&file_table, -1, i, rename_src[i].p->one);
395
hash.h
+7
@@ -40,4 +40,11 @@ static inline void init_hash(struct hash_table *table)
40 table->array = NULL;
41 }
42
43 +static inline void preallocate_hash(struct hash_table *table, unsigned int elts)
44 +{
45 + assert(table->size == 0 && table->nr == 0 && table->array == NULL);
46 + table->size = elts * 2;
47 + table->array = xcalloc(sizeof(struct hash_table_entry), table->size);
48 +}
49 +
50 #endif
name-hash.c
+2
@@ -92,6 +92,8 @@ static void lazy_init_name_hash(struct index_state *istate)
92
93 if (istate->name_hash_initialized)
94 return;
95 + if (istate->cache_nr)
96 + preallocate_hash(&istate->name_hash, istate->cache_nr);
97 for (nr = 0; nr < istate->cache_nr; nr++)
98 hash_index_entry(istate, istate->cache[nr]);
99 istate->name_hash_initialized = 1;