Skip to content

Commit

Permalink
add shortcut around syscalls when file not found in win32_stat
Browse files Browse the repository at this point in the history
win32_stat on success makes ~7 system calls, some from perl, some from CRT,
but on failure, typically file not found, the perl syscalls fails, then the
CRT stat runs, and fails too, so 5 mostly failing system calls are done
for file not found. If the perl syscall says file not found, the
file wont magically come into existence in the next 10-1000 us for the
CRT's syscalls, so skip calling the CRT and the additional syscalls
if the perl didn't find the file. This patch reduces the number of syscalls
from 5 to 1 for file not found for a win32 perl stat. Benchmark and
profiling info is attached to RT ticket for this patch. Note CreateFile on
a dir fails with ERROR_ACCESS_DENIED so in some cases, a failed CreateFile
is still a successful CRT stat() which does things differently so dirs can
be opened.
  • Loading branch information
bulk88 authored and tonycoz committed Feb 10, 2016
1 parent 3066fc0 commit d7a7ed7
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pod/perldelta.pod
Expand Up @@ -102,6 +102,11 @@ This empty function call now takes about a third less time to execute:

sub f{} f();

=item *

On Win32, C<stat>ing or C<-X>ing a path, if the file or directory does not exist
is now 3.5x faster on a SSD (or any drive) than before.

=back

=head1 Modules and Pragmata
Expand Down
8 changes: 8 additions & 0 deletions win32/win32.c
Expand Up @@ -1514,6 +1514,14 @@ win32_stat(const char *path, Stat_t *sbuf)
nlink = bhi.nNumberOfLinks;
CloseHandle(handle);
}
else {
DWORD err = GetLastError();
/* very common case, skip CRT stat and its also failing syscalls */
if(err == ERROR_FILE_NOT_FOUND) {
errno = ENOENT;
return -1;
}
}
}

/* path will be mapped correctly above */
Expand Down

0 comments on commit d7a7ed7

Please sign in to comment.