diff options
author | Karsten Blees <karsten.blees@gmail.com> | 2013-04-15 21:13:35 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-04-15 12:34:01 -0700 |
commit | 8aaf8d7728e8ac50cbf6bcad05b6e896d4e69e0b (patch) | |
tree | 2d5e859c61225f786a0b49432ac97127dde5dd2b /dir.c | |
parent | b07bc8c8c3c492d657a8bedf04ff939763ea8222 (diff) | |
download | git-8aaf8d7728e8ac50cbf6bcad05b6e896d4e69e0b.tar.gz |
dir.c: git-status: avoid is_excluded checks for tracked files
Checking if a file is in the index is much faster (hashtable lookup) than
checking if the file is excluded (linear search over exclude patterns).
Skip is_excluded checks for files: move the cache_name_exists check from
treat_file to treat_one_path and return early if the file is tracked.
This can safely be done as all other code paths also return path_ignored
for tracked files, and dir_add_ignored skips tracked files as well.
There's just one line left in treat_file, so move this to treat_one_path
as well.
Here's some performance data for git-status from the linux and WebKit
repos (best of 10 runs on a Debian Linux on SSD, core.preloadIndex=true):
| status | status --ignored
| linux | WebKit | linux | WebKit
-------+-------+--------+-------+---------
before | 0.218 | 1.583 | 0.321 | 2.579
after | 0.156 | 0.988 | 0.202 | 1.279
gain | 1.397 | 1.602 | 1.589 | 2.016
Signed-off-by: Karsten Blees <blees@dcon.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 38 |
1 files changed, 11 insertions, 27 deletions
@@ -1067,28 +1067,6 @@ static enum directory_treatment treat_directory(struct dir_struct *dir, } /* - * Decide what to do when we find a file while traversing the - * filesystem. Mostly two cases: - * - * 1. We are looking for ignored files - * (a) File is ignored, include it - * (b) File is in ignored path, include it - * (c) File is not ignored, exclude it - * - * 2. Other scenarios, include the file if not excluded - * - * Return 1 for exclude, 0 for include. - */ -static int treat_file(struct dir_struct *dir, struct strbuf *path, int exclude) -{ - /* Always exclude indexed files */ - if (index_name_exists(&the_index, path->buf, path->len, ignore_case)) - return 1; - - return exclude == !(dir->flags & DIR_SHOW_IGNORED); -} - -/* * This is an inexact early pruning of any recursive directory * reading - if the path cannot possibly be in the pathspec, * return true, and we'll skip it early. @@ -1211,7 +1189,16 @@ static enum path_treatment treat_one_path(struct dir_struct *dir, const struct path_simplify *simplify, int dtype, struct dirent *de) { - int exclude = is_excluded(dir, path->buf, &dtype); + int exclude; + if (dtype == DT_UNKNOWN) + dtype = get_dtype(de, path->buf, path->len); + + /* Always exclude indexed files */ + if (dtype != DT_DIR && + cache_name_exists(path->buf, path->len, ignore_case)) + return path_ignored; + + exclude = is_excluded(dir, path->buf, &dtype); if (exclude && (dir->flags & DIR_COLLECT_IGNORED) && exclude_matches_pathspec(path->buf, path->len, simplify)) dir_add_ignored(dir, path->buf, path->len); @@ -1223,9 +1210,6 @@ static enum path_treatment treat_one_path(struct dir_struct *dir, if (exclude && !(dir->flags & DIR_SHOW_IGNORED)) return path_ignored; - if (dtype == DT_UNKNOWN) - dtype = get_dtype(de, path->buf, path->len); - switch (dtype) { default: return path_ignored; @@ -1242,7 +1226,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir, break; case DT_REG: case DT_LNK: - if (treat_file(dir, path, exclude)) + if (exclude == !(dir->flags & DIR_SHOW_IGNORED)) return path_ignored; break; } |