mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +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
|
var ret []Port
|
||||||
|
|
||||||
// skip header row
|
// skip header row
|
||||||
_, err := r.ReadString('\n')
|
_, err := r.ReadSlice('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -93,7 +93,20 @@ func parsePorts(r *bufio.Reader, fileBase string) ([]Port, error) {
|
|||||||
wantRemote = mem.S(v6Any)
|
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 {
|
for err == nil {
|
||||||
line, err := r.ReadSlice('\n')
|
line, err := r.ReadSlice('\n')
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
@ -102,9 +115,25 @@ func parsePorts(r *bufio.Reader, fileBase string) ([]Port, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
rows++
|
||||||
|
if rows >= maxRows {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if len(line) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if i := fieldIndex(line, 2); i == -1 ||
|
// On the first row of output, find the index of the 3rd field (index 2),
|
||||||
!mem.HasPrefix(mem.B(line).SliceFrom(i), wantRemote) {
|
// 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.
|
// Fast path for not being a listener port.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user