trace: measure where the time is spent in the index-heavy operations
All the known heavy code blocks are measured (except object database access). This should help identify if an optimization is effective or not. An unoptimized git-status would give something like below: 0.001791141 s: read cache ... 0.004011363 s: preload index 0.000516161 s: refresh index 0.003139257 s: git command: ... 'status' '--porcelain=2' 0.006788129 s: diff-files 0.002090267 s: diff-index 0.001885735 s: initialize name hash 0.032013138 s: read directory 0.051781209 s: git command: './git' 'status' 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
Jan 27, 2018 at 19:27 UTC
ca54d9baa4a8e73141d4c963245ee6f09dcc994d
5 files changed
+18
diff-lib.c
+4
@@ -92,6 +92,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
92
int diff_unmerged_stage = revs->max_count;
93
unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
94
? CE_MATCH_RACY_IS_DIRTY : 0);
95
+ uint64_t start = getnanotime();
96
97
diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
98
@@ -246,6 +247,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
247
}
248
diffcore_std(&revs->diffopt);
249
diff_flush(&revs->diffopt);
250
+ trace_performance_since(start, "diff-files");
251
return 0;
252
}
253
@@ -512,6 +514,7 @@ static int diff_cache(struct rev_info *revs,
514
int run_diff_index(struct rev_info *revs, int cached)
515
{
516
struct object_array_entry *ent;
517
+ uint64_t start = getnanotime();
518
519
ent = revs->pending.objects;
520
if (diff_cache(revs, &ent->item->oid, ent->name, cached))
@@ -521,6 +524,7 @@ int run_diff_index(struct rev_info *revs, int cached)
524
diffcore_fix_diff_index(&revs->diffopt);
525
diffcore_std(&revs->diffopt);
526
diff_flush(&revs->diffopt);
527
+ trace_performance_since(start, "diff-index");
528
return 0;
529
}
530
dir.c
+2
@@ -2248,6 +2248,7 @@ int read_directory(struct dir_struct *dir, struct index_state *istate,
2248
const char *path, int len, const struct pathspec *pathspec)
2249
{
2250
struct untracked_cache_dir *untracked;
2251
+ uint64_t start = getnanotime();
2252
2253
if (has_symlink_leading_path(path, len))
2254
return dir->nr;
@@ -2286,6 +2287,7 @@ int read_directory(struct dir_struct *dir, struct index_state *istate,
2287
dir->nr = i;
2288
}
2289
2290
+ trace_performance_since(start, "read directory %.*s", len, path);
2291
if (dir->untracked) {
2292
static struct trace_key trace_untracked_stats = TRACE_KEY_INIT(UNTRACKED_STATS);
2293
trace_printf_key(&trace_untracked_stats,
name-hash.c
+3
@@ -578,6 +578,8 @@ static void threaded_lazy_init_name_hash(
578
579
static void lazy_init_name_hash(struct index_state *istate)
580
{
581
+ uint64_t start = getnanotime();
582
+
583
if (istate->name_hash_initialized)
584
return;
585
hashmap_init(&istate->name_hash, cache_entry_cmp, NULL, istate->cache_nr);
@@ -600,6 +602,7 @@ static void lazy_init_name_hash(struct index_state *istate)
602
}
603
604
istate->name_hash_initialized = 1;
605
+ trace_performance_since(start, "initialize name hash");
606
}
607
608
/*
preload-index.c
+2
@@ -78,6 +78,7 @@ static void preload_index(struct index_state *index,
78
{
79
int threads, i, work, offset;
80
struct thread_data data[MAX_PARALLEL];
81
+ uint64_t start = getnanotime();
82
83
if (!core_preload_index)
84
return;
@@ -108,6 +109,7 @@ static void preload_index(struct index_state *index,
109
if (pthread_join(p->pthread, NULL))
110
die("unable to join threaded lstat");
111
}
112
+ trace_performance_since(start, "preload index");
113
}
114
#endif
115
read-cache.c
+7
@@ -1372,6 +1372,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
1372
const char *typechange_fmt;
1373
const char *added_fmt;
1374
const char *unmerged_fmt;
1375
+ uint64_t start = getnanotime();
1376
1377
modified_fmt = (in_porcelain ? "M\t%s\n" : "%s: needs update\n");
1378
deleted_fmt = (in_porcelain ? "D\t%s\n" : "%s: needs update\n");
@@ -1442,6 +1443,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
1443
1444
replace_index_entry(istate, i, new);
1445
}
1446
+ trace_performance_since(start, "refresh index");
1447
return has_errors;
1448
}
1449
@@ -1873,6 +1875,7 @@ static void freshen_shared_index(char *base_sha1_hex, int warn)
1875
1876
int read_index_from(struct index_state *istate, const char *path)
1877
{
1878
+ uint64_t start = getnanotime();
1879
struct split_index *split_index;
1880
int ret;
1881
char *base_sha1_hex;
@@ -1883,6 +1886,7 @@ int read_index_from(struct index_state *istate, const char *path)
1886
return istate->cache_nr;
1887
1888
ret = do_read_index(istate, path, 0);
1889
+ trace_performance_since(start, "read cache %s", path);
1890
1891
split_index = istate->split_index;
1892
if (!split_index || is_null_sha1(split_index->base_sha1)) {
@@ -1906,6 +1910,7 @@ int read_index_from(struct index_state *istate, const char *path)
1910
freshen_shared_index(base_sha1_hex, 0);
1911
merge_base_index(istate);
1912
post_read_index_from(istate);
1913
+ trace_performance_since(start, "read cache %s", base_path);
1914
return ret;
1915
}
1916
@@ -2234,6 +2239,7 @@ void update_index_if_able(struct index_state *istate, struct lock_file *lockfile
2239
static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
2240
int strip_extensions)
2241
{
2242
+ uint64_t start = getnanotime();
2243
int newfd = tempfile->fd;
2244
git_SHA_CTX c;
2245
struct cache_header hdr;
@@ -2374,6 +2380,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
2380
return -1;
2381
istate->timestamp.sec = (unsigned int)st.st_mtime;
2382
istate->timestamp.nsec = ST_MTIME_NSEC(st);
2383
+ trace_performance_since(start, "write index, changed mask = %x", istate->cache_changed);
2384
return 0;
2385
}
2386