prep_exclude is only necessary when we enter or leave a directory. Now it's called for every entry in a directory. With this patch, the number of prep_exclude calls in webkit.git goes from 188k down to 11k. This patch does not make exclude any faster, but it prepares for making prep_exclude heavier in terms of computation, where a large number of calls may have bigger impacts. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- dir.c | 10 +++++++++- dir.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dir.c b/dir.c index 58739f3..f8f7a7e 100644 --- a/dir.c +++ b/dir.c @@ -804,7 +804,10 @@ static struct exclude *last_exclude_matching(struct dir_struct *dir, basename = (basename) ? basename+1 : pathname; START_CLOCK(); - prep_exclude(dir, pathname, basename-pathname); + if (!dir->exclude_prepared) { + prep_exclude(dir, pathname, basename-pathname); + dir->exclude_prepared = 1; + } STOP_CLOCK(tv_prep_exclude); START_CLOCK(); @@ -894,6 +897,7 @@ struct exclude *last_exclude_matching_path(struct path_exclude_check *check, if (ch == '/') { int dt = DT_DIR; + check->dir->exclude_prepared = 0; exclude = last_exclude_matching(check->dir, path->buf, path->len, &dt); @@ -908,6 +912,7 @@ struct exclude *last_exclude_matching_path(struct path_exclude_check *check, /* An entry in the index; cannot be a directory with subentries */ strbuf_setlen(path, 0); + check->dir->exclude_prepared = 0; return last_exclude_matching(check->dir, name, namelen, dtype); } @@ -1394,6 +1399,7 @@ static int read_directory_recursive(struct dir_struct *dir, if (!fdir) goto out; + dir->exclude_prepared = 0; while ((de = readdir(fdir)) != NULL) { switch (treat_path(dir, de, &path, baselen, simplify)) { case path_recurse: @@ -1415,6 +1421,7 @@ static int read_directory_recursive(struct dir_struct *dir, } closedir(fdir); out: + dir->exclude_prepared = 0; strbuf_release(&path); return contents; @@ -1486,6 +1493,7 @@ static int treat_leading_path(struct dir_struct *dir, break; if (simplify_away(sb.buf, sb.len, simplify)) break; + dir->exclude_prepared = 0; if (treat_one_path(dir, &sb, simplify, DT_DIR, NULL) == path_ignored) break; /* do not recurse into it */ diff --git a/dir.h b/dir.h index 560ade4..0748407 100644 --- a/dir.h +++ b/dir.h @@ -86,6 +86,7 @@ struct dir_struct { /* Exclude info */ const char *exclude_per_dir; + int exclude_prepared; /* * We maintain three groups of exclude pattern lists: -- 1.8.1.2.536.gf441e6d -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html