summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Blees <karsten.blees@gmail.com>2013-04-15 19:13:35 (GMT)
committerJunio C Hamano <gitster@pobox.com>2013-04-15 19:34:01 (GMT)
commit8aaf8d7728e8ac50cbf6bcad05b6e896d4e69e0b (patch)
tree2d5e859c61225f786a0b49432ac97127dde5dd2b
parentb07bc8c8c3c492d657a8bedf04ff939763ea8222 (diff)
downloadgit-8aaf8d7728e8ac50cbf6bcad05b6e896d4e69e0b.zip
git-8aaf8d7728e8ac50cbf6bcad05b6e896d4e69e0b.tar.gz
git-8aaf8d7728e8ac50cbf6bcad05b6e896d4e69e0b.tar.bz2
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>
-rw-r--r--dir.c38
1 files changed, 11 insertions, 27 deletions
diff --git a/dir.c b/dir.c
index 4739760..9fc032f 100644
--- a/dir.c
+++ b/dir.c
@@ -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;
}