diff options
| author | qmuntal <quimmuntal@gmail.com> | 2022-11-22 18:46:35 +0100 |
|---|---|---|
| committer | Quim Muntal <quimmuntal@gmail.com> | 2023-01-24 13:26:00 +0000 |
| commit | 1951857ec07c1d491e1836770a647d3902934a67 (patch) | |
| tree | c6d132e27692470402908a581ae3b3c893ff7366 /src/internal/syscall/windows/syscall_windows.go | |
| parent | 7b5a34418cd32ec4d2c0f7d6e4c7e6fe7585a17f (diff) | |
| download | go-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.go | 20 |
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 |
