portlist: further reduce allocations on Linux

Make Linux parsePorts also an append-style API and attach it to
caller's provided append base memory.

And add a little string intern pool in front of the []byte to string
for inode names.

    name       old time/op    new time/op    delta
    GetList-8    11.1ms ± 4%     9.8ms ± 6%  -11.68%  (p=0.000 n=9+10)

    name       old alloc/op   new alloc/op   delta
    GetList-8    92.8kB ± 2%    79.7kB ± 0%  -14.11%  (p=0.000 n=10+9)

    name       old allocs/op  new allocs/op  delta
    GetList-8     2.94k ± 1%     2.76k ± 0%   -6.16%  (p=0.000 n=10+10)

More coming. (the bulk of the allocations are in addProcesses and
filesystem operations, most of which we should usually be able to
skip)

Updates #5958

Change-Id: I3f0c03646d314a16fef7f8346aefa7d5c96701e7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2022-10-22 09:29:37 -07:00
committed by Brad Fitzpatrick
parent def089f9c9
commit 7149155b80
3 changed files with 47 additions and 14 deletions

View File

@ -76,6 +76,7 @@ func TestParsePorts(t *testing.T) {
},
}
stringCache := new(internedStrings)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
buf := bytes.NewBufferString(tt.in)
@ -84,7 +85,7 @@ func TestParsePorts(t *testing.T) {
if tt.file != "" {
file = tt.file
}
got, err := parsePorts(r, file)
got, err := appendParsePorts(nil, stringCache, r, file)
if err != nil {
t.Fatal(err)
}
@ -116,11 +117,12 @@ func BenchmarkParsePorts(b *testing.B) {
r := bytes.NewReader(contents.Bytes())
br := bufio.NewReader(&contents)
stringCache := new(internedStrings)
b.ResetTimer()
for i := 0; i < b.N; i++ {
r.Seek(0, io.SeekStart)
br.Reset(r)
got, err := parsePorts(br, "tcp6")
got, err := appendParsePorts(nil, stringCache, br, "tcp6")
if err != nil {
b.Fatal(err)
}