This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add shortcut around syscalls when file not found in win32_stat
authorDaniel Dragan <bulk88@hotmail.com>
Wed, 10 Feb 2016 20:47:44 +0000 (15:47 -0500)
committerTony Cook <tony@develop-help.com>
Wed, 10 Feb 2016 22:01:33 +0000 (09:01 +1100)
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.

pod/perldelta.pod
win32/win32.c

index 0a7d4b0..d95df70 100644 (file)
@@ -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
index b410f66..651b97b 100644 (file)
@@ -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 */