1
0
mirror of https://github.com/golang/go synced 2024-11-13 20:20:30 -07:00
go/src/os/dir_windows.go
Alex Brainman 6dcaa095c5 os: avoid calulating fileStat.path until it is needed
This CL improves

on my Windows 7

name         old time/op    new time/op    delta
Readdirname    58.1µs ± 1%    58.1µs ± 0%     ~     (p=0.817 n=8+8)
Readdir        58.0µs ± 3%    57.8µs ± 0%     ~     (p=0.944 n=9+8)

name         old alloc/op   new alloc/op   delta
Readdirname    3.03kB ± 0%    2.84kB ± 0%   -6.33%  (p=0.000 n=10+10)
Readdir        3.00kB ± 0%    2.81kB ± 0%   -6.40%  (p=0.000 n=10+10)

name         old allocs/op  new allocs/op  delta
Readdirname      34.0 ± 0%      30.0 ± 0%  -11.76%  (p=0.000 n=10+10)
Readdir          33.0 ± 0%      29.0 ± 0%  -12.12%  (p=0.000 n=10+10)

on my Windows XP

name           old time/op    new time/op    delta
Readdirname-2    85.5µs ± 0%    84.0µs ± 0%   -1.83%  (p=0.000 n=10+10)
Readdir-2        84.6µs ± 0%    83.5µs ± 0%   -1.31%  (p=0.000 n=10+9)

name           old alloc/op   new alloc/op   delta
Readdirname-2    6.52kB ± 0%    5.66kB ± 0%  -13.25%  (p=0.000 n=10+10)
Readdir-2        6.39kB ± 0%    5.53kB ± 0%  -13.52%  (p=0.000 n=10+10)

name           old allocs/op  new allocs/op  delta
Readdirname-2      78.0 ± 0%      66.0 ± 0%  -15.38%  (p=0.000 n=10+10)
Readdir-2          77.0 ± 0%      65.0 ± 0%  -15.58%  (p=0.000 n=10+10)

Change-Id: I5d698eca86b8e94a46b6cfbd5947898b7b3fbdbd
Reviewed-on: https://go-review.googlesource.com/42894
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-05-09 04:47:47 +00:00

79 lines
1.7 KiB
Go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package os
import (
"io"
"runtime"
"syscall"
)
func (file *File) readdir(n int) (fi []FileInfo, err error) {
if file == nil {
return nil, syscall.EINVAL
}
if !file.isdir() {
return nil, &PathError{"Readdir", file.name, syscall.ENOTDIR}
}
wantAll := n <= 0
size := n
if wantAll {
n = -1
size = 100
}
fi = make([]FileInfo, 0, size) // Empty with room to grow.
d := &file.dirinfo.data
for n != 0 && !file.dirinfo.isempty {
if file.dirinfo.needdata {
e := file.pfd.FindNextFile(d)
runtime.KeepAlive(file)
if e != nil {
if e == syscall.ERROR_NO_MORE_FILES {
break
} else {
err = &PathError{"FindNextFile", file.name, e}
if !wantAll {
fi = nil
}
return
}
}
}
file.dirinfo.needdata = true
name := syscall.UTF16ToString(d.FileName[0:])
if name == "." || name == ".." { // Useless names
continue
}
f := &fileStat{
name: name,
sys: syscall.Win32FileAttributeData{
FileAttributes: d.FileAttributes,
CreationTime: d.CreationTime,
LastAccessTime: d.LastAccessTime,
LastWriteTime: d.LastWriteTime,
FileSizeHigh: d.FileSizeHigh,
FileSizeLow: d.FileSizeLow,
},
path: file.dirinfo.path,
appendNameToPath: true,
}
n--
fi = append(fi, f)
}
if !wantAll && len(fi) == 0 {
return fi, io.EOF
}
return fi, nil
}
func (file *File) readdirnames(n int) (names []string, err error) {
fis, err := file.Readdir(n)
names = make([]string, len(fis))
for i, fi := range fis {
names[i] = fi.Name()
}
return names, err
}