Use cached file attributes during matching

When _DIRENT_HAVE_D_TYPE is defined, struct dirent defines a
d_type member that will indicate if the type of the entry. This
saves an expensive syscall for each entry which can really add
up on slow filesystems (such as VirtualBox's shared folder FS).

We use the same logic as do_isfile, and return a 1 when the entry
is not a directory, and a 0 otherwise.

For our large project this reduced the overall stat syscalls from
118,865 to 39,177 and total premake generation time from 59,977ms
to 20,729ms on vboxsf.

See: https://gist.github.com/mendsley/4b56932056d5c231a94d1cdefd15c027
This commit is contained in:
Matthew Endsley 2016-06-30 00:05:50 +00:00
parent 5719c8f92a
commit bd19650f92

View File

@ -141,14 +141,26 @@ int os_matchname(lua_State* L)
int os_matchisfile(lua_State* L)
{
const char* fname;
MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
lua_pushfstring(L, "%s/%s", m->path, m->entry->d_name);
fname = lua_tostring(L, -1);
lua_pop(L, 1);
#if defined(_DIRENT_HAVE_D_TYPE)
if (m->entry->d_type == DT_DIR)
{
lua_pushboolean(L, 0);
}
else if (m->entry->d_type == DT_REG)
{
lua_pushboolean(L, 1);
}
else
#endif
{
const char* fname;
lua_pushfstring(L, "%s/%s", m->path, m->entry->d_name);
fname = lua_tostring(L, -1);
lua_pop(L, 1);
lua_pushboolean(L, do_isfile(fname));
lua_pushboolean(L, do_isfile(fname));
}
return 1;
}