mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 11:05:45 +00:00
portlist: cache field index position between runs, cut two more allocs (Linux)
name old time/op new time/op delta ParsePorts-6 6.41ms ± 7% 3.15ms ± 2% -50.84% (p=0.000 n=9+9) name old alloc/op new alloc/op delta ParsePorts-6 408B ± 0% 216B ± 0% -47.06% (p=0.002 n=8+10) name old allocs/op new allocs/op delta ParsePorts-6 7.00 ± 0% 4.00 ± 0% -42.86% (p=0.000 n=10+10) Updates tailscale/corp#2566 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
61f201f33d
commit
0eb6cc9321
@ -81,7 +81,7 @@ func parsePorts(r *bufio.Reader, fileBase string) ([]Port, error) {
|
||||
var ret []Port
|
||||
|
||||
// skip header row
|
||||
_, err := r.ReadString('\n')
|
||||
_, err := r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -93,7 +93,20 @@ func parsePorts(r *bufio.Reader, fileBase string) ([]Port, error) {
|
||||
wantRemote = mem.S(v6Any)
|
||||
}
|
||||
|
||||
var inoBuf []byte
|
||||
// remoteIndex is the index within a line to the remote address field.
|
||||
// -1 means not yet found.
|
||||
remoteIndex := -1
|
||||
|
||||
// Add an upper bound on how many rows we'll attempt to read just
|
||||
// to make sure this doesn't consume too much of their CPU.
|
||||
// TODO(bradfitz,crawshaw): adaptively adjust polling interval as function
|
||||
// of open sockets.
|
||||
const maxRows = 1e6
|
||||
rows := 0
|
||||
|
||||
// Scratch buffer for making inode strings.
|
||||
inoBuf := make([]byte, 0, 50)
|
||||
|
||||
for err == nil {
|
||||
line, err := r.ReadSlice('\n')
|
||||
if err == io.EOF {
|
||||
@ -102,9 +115,25 @@ func parsePorts(r *bufio.Reader, fileBase string) ([]Port, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows++
|
||||
if rows >= maxRows {
|
||||
break
|
||||
}
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if i := fieldIndex(line, 2); i == -1 ||
|
||||
!mem.HasPrefix(mem.B(line).SliceFrom(i), wantRemote) {
|
||||
// On the first row of output, find the index of the 3rd field (index 2),
|
||||
// the remote address. All the rows are aligned, at least until 4 billion open
|
||||
// TCP connections, per the Linux get_tcp4_sock's "%4d: " on an int i.
|
||||
if remoteIndex == -1 {
|
||||
remoteIndex = fieldIndex(line, 2)
|
||||
if remoteIndex == -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(line) < remoteIndex || !mem.HasPrefix(mem.B(line).SliceFrom(remoteIndex), wantRemote) {
|
||||
// Fast path for not being a listener port.
|
||||
continue
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user