Commit 26bb86c1 authored by Richard Gobeille's avatar Richard Gobeille
Browse files

engine: implement buildvfs_exists() using GetFileAttributes() on Windows and...

engine: implement buildvfs_exists() using GetFileAttributes() on Windows and stat() elsewhere, FORCE_INLINE some stuff in vfs.h

The rationale behind this change is that I was profiling CPU use during loads of particularly heavy .def files (10000+ items) and discovered an inappropriate amount of CPU time was being spent inside access(). So, I did some research and found several cases where people on stackoverflow etc had asked what the fastest method of determining whether or not a file exists was, with the results of several benchmarks being given as answers. GetFileAttributes() seemed to win on Windows and stat() seemed to win on Linux, and I did not see any results where access() was a serious contender when included in the spread of tested functions, with the best I saw being 1100-something nanoseconds for access() and 800-something for stat().

This whole thing would be faster if we just read in the entire directory index and matched files against it ourselves with just the few API calls involved with retrieving the index, but access to uncooked data littered across a directory tree isn't really something I give a shit about optimizing further at the moment.
parent 223164a1
......@@ -102,7 +102,7 @@ using buildvfs_FILE = FILE *;
#define buildvfs_rewind(fp) rewind(fp)
#define buildvfs_fflush(fp) fflush(fp)
static inline int64_t buildvfs_length(int fd)
static FORCE_INLINE int64_t buildvfs_length(int fd)
{
#ifdef _WIN32
return filelength(fd);
......@@ -128,7 +128,7 @@ using buildvfs_fd = int;
#define buildvfs_lseek_abs(fd, o) lseek((fd), (o), SEEK_SET)
#define buildvfs_lseek_rel(fd, o) lseek((fd), (o), SEEK_CUR)
static inline int64_t buildvfs_flength(FILE * f)
static FORCE_INLINE int64_t buildvfs_flength(FILE * f)
{
#ifdef _WIN32
return filelength(_fileno(f));
......@@ -136,8 +136,18 @@ static inline int64_t buildvfs_flength(FILE * f)
return buildvfs_length(fileno(f));
#endif
}
#define buildvfs_exists(fn) (access((fn), F_OK) == 0)
static inline int buildvfs_isdir(char const *path)
static FORCE_INLINE int buildvfs_exists(char const* path)
{
#ifdef _WIN32
return GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES;
#else
struct Bstat st;
return !Bstat(path, &st);
#endif
}
static FORCE_INLINE int buildvfs_isdir(char const *path)
{
struct Bstat st;
return (Bstat(path, &st) ? 0 : (st.st_mode & S_IFDIR) == S_IFDIR);
......@@ -150,20 +160,20 @@ static inline int buildvfs_isdir(char const *path)
if (fileptr) { buildvfs_fclose(fileptr); fileptr = buildvfs_FILE{}; } \
} while (0)
static inline void buildvfs_fputstrptr(buildvfs_FILE fp, char const * str)
static FORCE_INLINE void buildvfs_fputstrptr(buildvfs_FILE fp, char const * str)
{
if (fp)
buildvfs_fwrite(str, 1, strlen(str), fp);
}
static inline void buildvfs_fputs(char const * str, buildvfs_FILE fp)
static FORCE_INLINE void buildvfs_fputs(char const * str, buildvfs_FILE fp)
{
if (fp)
buildvfs_fwrite(str, 1, strlen(str), fp);
}
template <size_t N>
static inline void buildvfs_fputstr(buildvfs_FILE fp, char const (&str)[N])
static FORCE_INLINE void buildvfs_fputstr(buildvfs_FILE fp, char const (&str)[N])
{
if (fp)
buildvfs_fwrite(&str, 1, N-1, fp);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment