Subject: Re: [PATCH/RFC v3 6/8] Add case insensitivity support when using git ls-files

From: Jonathan Nieder <[email-masked]>
Date: Mon, 4 Oct 2010 12:03:42 -0500

Joshua Jensen wrote:

> I'm running on a really, really fast machine, a Xeon X5560.  The
> difference in time for the above code versus what is in the patch
> seems to average about 0.07 seconds.

The useful information would be a percentage...

> Remember, this is an
> incredibly fast machine, and I imagine it will be worse on machines
> with slower processors and less cache.

... but the subarch and cache size may indeed also be relevant.

Here's a revised version of the ugly speed hack.  Using a separate
function like this is probably a bad idea unless it speeds things up.

/* Returns match length, or -1 for mismatch. */
static inline int match_until_glob_special(const char *match, const char *name,
						int namelen, int ignore_case)
{
	int remaining = namelen;
	for (;;) {
		unsigned char c1 = (ignore_case) ? tolower(*match) : *match;
		unsigned char c2 = (ignore_case) ? tolower(*name) : *name;
		if (c1 == '\0' || is_glob_special(c1))
			return namelen - remaining;
		if (c1 != c2)
			return -1;
		match++;
		name++;
		remaining--;
	}
}

[...]
	int matched;

	/* If the match was just the prefix, we matched */
	if (!*match)
		return MATCHED_RECURSIVELY;

	/*
	 * Note: this funny "if" is to ensure each case gets inlined separately.
	 * Please don't optimize it away unless you've checked the assembler
	 * to ensure it wasn't helping.
	 */
	if (ignore_case)
		matched = match_until_glob_special(match, name, namelen, 1);
	else
		matched = match_until_glob_special(match, name, namelen, 0);

	if (matched == -1)	/* mismatch! */
		return 0;

	match += matched;
	name += matched;
	remaining -= matched;