Re: [PATCH] Avoid running lstat(2) on the same cache entry.
- From
Linus Torvalds <torvalds@linux-foundation.org>
- Date
- Jan 19, 2008, 19:47 UTC
- Message-ID
- <alpine.LFD.1.00.0801191133330.2957@woody.linux-foundation.org>
- In-Reply-To
- <7vfxwu9s2z.fsf@gitster.siamese.dyndns.org>
On Fri, 18 Jan 2008, Junio C Hamano wrote:
> > Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
> * Again, this is a rebase on top of your "Updated in-memory > index". "echo >>Makefile && git commit -m test Makefile" in > the kernel repository does 23k lstat(2) with this patch, 46k > without.
Sadly, doing a simple "git commit" without anything else, will still apparently get us 69230 lstat() calls, with or without this patch. So we get 3 lstat() calls per path.
The call trace for the first one is
- builtin-commit.c: line 786 prepare_index refresh_index refresh_cache_ent lstat
while the second one is
- builtin-commit.c: line 793 prepare_log_message run_status wt_status_print wt_status_print_changed run_diff_files lstat
and the third one is
- builtin-commit.c: line 795 run_status wt_status_print wt_status_print_changed run_diff_files lstat
and the reason is that - "run_diff_files()" doesn't honor ce_uptodate - ..but even if it did, wt_status_print_changed() does a wt_read_cache() which will invalidate and re-read the index!
The first problem is trivially fixed (appended), the second one is notas trivial.
Linus --- diff-lib.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/diff-lib.c b/diff-lib.c index 4a05b02..5d5a950 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -435,6 +435,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option) continue; } + if (ce_uptodate(ce)) + continue; if (lstat(ce->name, &st) < 0) { if (errno != ENOENT && errno != ENOTDIR) { perror(ce->name);