mirror of
https://github.com/golang/go
synced 2024-11-19 00:44:40 -07:00
os/user: cache the result of user.Current
This has a notable impact on systems with very large passwd files. Before: BenchmarkCurrent-12 30000 42546 ns/op After: BenchmarkCurrent-12 20000000 77.5 ns/op Saved in perf dashboard: https://perf.golang.org/search?q=upload:20170206.1 Fixes #11625 Change-Id: Iebc9bf122cc64a4cab24ac06843c7b2bc450ded9 Reviewed-on: https://go-review.googlesource.com/36391 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
fd37b8ccf2
commit
2ca5d105b0
@ -4,20 +4,40 @@
|
||||
|
||||
package user
|
||||
|
||||
import "sync"
|
||||
|
||||
// Current returns the current user.
|
||||
func Current() (*User, error) {
|
||||
return current()
|
||||
cache.Do(func() { cache.u, cache.err = current() })
|
||||
if cache.err != nil {
|
||||
return nil, cache.err
|
||||
}
|
||||
u := *cache.u // copy
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
// cache of the current user
|
||||
var cache struct {
|
||||
sync.Once
|
||||
u *User
|
||||
err error
|
||||
}
|
||||
|
||||
// Lookup looks up a user by username. If the user cannot be found, the
|
||||
// returned error is of type UnknownUserError.
|
||||
func Lookup(username string) (*User, error) {
|
||||
if u, err := Current(); err == nil && u.Username == username {
|
||||
return u, err
|
||||
}
|
||||
return lookupUser(username)
|
||||
}
|
||||
|
||||
// LookupId looks up a user by userid. If the user cannot be found, the
|
||||
// returned error is of type UnknownUserIdError.
|
||||
func LookupId(uid string) (*User, error) {
|
||||
if u, err := Current(); err == nil && u.Uid == uid {
|
||||
return u, err
|
||||
}
|
||||
return lookupUserId(uid)
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,12 @@ func TestCurrent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCurrent(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
Current()
|
||||
}
|
||||
}
|
||||
|
||||
func compare(t *testing.T, want, got *User) {
|
||||
if want.Uid != got.Uid {
|
||||
t.Errorf("got Uid=%q; want %q", got.Uid, want.Uid)
|
||||
|
Loading…
Reference in New Issue
Block a user