aboutsummaryrefslogtreecommitdiff
path: root/src/internal/syscall/windows/syscall_windows.go
diff options
context:
space:
mode:
authorqmuntal <quimmuntal@gmail.com>2022-11-22 18:46:35 +0100
committerQuim Muntal <quimmuntal@gmail.com>2023-01-24 13:26:00 +0000
commit1951857ec07c1d491e1836770a647d3902934a67 (patch)
treec6d132e27692470402908a581ae3b3c893ff7366 /src/internal/syscall/windows/syscall_windows.go
parent7b5a34418cd32ec4d2c0f7d6e4c7e6fe7585a17f (diff)
downloadgo-1951857ec07c1d491e1836770a647d3902934a67.tar.xz
os: use handle based APIs to read directories on windows
This CL updates File.readdir() on windows so it uses GetFileInformationByHandleEx with FILE_ID_BOTH_DIR_INFO instead of Find* APIs. The former is more performant because it allows us to buffer IO calls and reduces the number of system calls, passing from 1 per file to 1 every ~100 files (depending on the size of the file name and the size of the buffer). This change improve performance of File.ReadDir by 20-30%. name old time/op new time/op delta ReadDir-12 562µs ±14% 385µs ± 9% -31.60% (p=0.000 n=9+9) name old alloc/op new alloc/op delta ReadDir-12 29.7kB ± 0% 29.5kB ± 0% -0.88% (p=0.000 n=8+10) name old allocs/op new allocs/op delta ReadDir-12 399 ± 0% 397 ± 0% -0.50% (p=0.000 n=10+10) This change also speeds up calls to os.SameFile when using FileStats returned from File.readdir(), as their file ID can be inferred while reading the directory. Change-Id: Id56a338ee66c39656b564105cac131099218fb5d Reviewed-on: https://go-review.googlesource.com/c/go/+/452995 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Run-TryBot: Quim Muntal <quimmuntal@gmail.com> Reviewed-by: Bryan Mills <bcmills@google.com>
Diffstat (limited to 'src/internal/syscall/windows/syscall_windows.go')
-rw-r--r--src/internal/syscall/windows/syscall_windows.go20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
index 8ace2a27e7..311d083f45 100644
--- a/src/internal/syscall/windows/syscall_windows.go
+++ b/src/internal/syscall/windows/syscall_windows.go
@@ -367,3 +367,23 @@ func LoadGetFinalPathNameByHandle() error {
//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
+
+type FILE_ID_BOTH_DIR_INFO struct {
+ NextEntryOffset uint32
+ FileIndex uint32
+ CreationTime syscall.Filetime
+ LastAccessTime syscall.Filetime
+ LastWriteTime syscall.Filetime
+ ChangeTime syscall.Filetime
+ EndOfFile uint64
+ AllocationSize uint64
+ FileAttributes uint32
+ FileNameLength uint32
+ EaSize uint32
+ ShortNameLength uint32
+ ShortName [12]uint16
+ FileID uint64
+ FileName [1]uint16
+}
+
+//sys GetVolumeInformationByHandle(file syscall.Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW