Skip to content

Commit 8aaf8d7

Browse files
kbleesgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b07bc8c commit 8aaf8d7

File tree

1 file changed

+11
-27
lines changed

1 file changed

+11
-27
lines changed

dir.c

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,28 +1066,6 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
10661066
return show_directory;
10671067
}
10681068

1069-
/*
1070-
* Decide what to do when we find a file while traversing the
1071-
* filesystem. Mostly two cases:
1072-
*
1073-
* 1. We are looking for ignored files
1074-
* (a) File is ignored, include it
1075-
* (b) File is in ignored path, include it
1076-
* (c) File is not ignored, exclude it
1077-
*
1078-
* 2. Other scenarios, include the file if not excluded
1079-
*
1080-
* Return 1 for exclude, 0 for include.
1081-
*/
1082-
static int treat_file(struct dir_struct *dir, struct strbuf *path, int exclude)
1083-
{
1084-
/* Always exclude indexed files */
1085-
if (index_name_exists(&the_index, path->buf, path->len, ignore_case))
1086-
return 1;
1087-
1088-
return exclude == !(dir->flags & DIR_SHOW_IGNORED);
1089-
}
1090-
10911069
/*
10921070
* This is an inexact early pruning of any recursive directory
10931071
* reading - if the path cannot possibly be in the pathspec,
@@ -1211,7 +1189,16 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
12111189
const struct path_simplify *simplify,
12121190
int dtype, struct dirent *de)
12131191
{
1214-
int exclude = is_excluded(dir, path->buf, &dtype);
1192+
int exclude;
1193+
if (dtype == DT_UNKNOWN)
1194+
dtype = get_dtype(de, path->buf, path->len);
1195+
1196+
/* Always exclude indexed files */
1197+
if (dtype != DT_DIR &&
1198+
cache_name_exists(path->buf, path->len, ignore_case))
1199+
return path_ignored;
1200+
1201+
exclude = is_excluded(dir, path->buf, &dtype);
12151202
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
12161203
&& exclude_matches_pathspec(path->buf, path->len, simplify))
12171204
dir_add_ignored(dir, path->buf, path->len);
@@ -1223,9 +1210,6 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
12231210
if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
12241211
return path_ignored;
12251212

1226-
if (dtype == DT_UNKNOWN)
1227-
dtype = get_dtype(de, path->buf, path->len);
1228-
12291213
switch (dtype) {
12301214
default:
12311215
return path_ignored;
@@ -1242,7 +1226,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
12421226
break;
12431227
case DT_REG:
12441228
case DT_LNK:
1245-
if (treat_file(dir, path, exclude))
1229+
if (exclude == !(dir->flags & DIR_SHOW_IGNORED))
12461230
return path_ignored;
12471231
break;
12481232
}

0 commit comments

Comments
 (0)