Commit Graph

8 Commits (a887ca7efe123afd711b17a1c2b6c9d28ca99a14)

Author SHA1 Message Date
Brad Fitzpatrick db2cc393af util/dirwalk, metrics, portlist: add new package for fast directory walking
This is similar to the golang.org/x/tools/internal/fastwalk I'd
previously written but not recursive and using mem.RO.

The metrics package already had some Linux-specific directory reading
code in it. Move that out to a new general package that can be reused
by portlist too, which helps its scanning of all /proc files:

    name                old time/op    new time/op    delta
    FindProcessNames-8    2.79ms ± 6%    2.45ms ± 7%  -12.11%  (p=0.000 n=10+10)

    name                old alloc/op   new alloc/op   delta
    FindProcessNames-8    62.9kB ± 0%    33.5kB ± 0%  -46.76%  (p=0.000 n=9+10)

    name                old allocs/op  new allocs/op  delta
    FindProcessNames-8     2.25k ± 0%     0.38k ± 0%  -82.98%  (p=0.000 n=9+10)

Change-Id: I75db393032c328f12d95c39f71c9742c375f207a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 036f70b7b4 portlist: refactor, introduce OS-specific types
Add an osImpl interface that can be stateful and thus more efficient
between calls. It will later be implemented by all OSes but for now
this change only adds a Linux implementation.

Remove Port.inode. It was only used by Linux and moves into its osImpl.

Don't reopen /proc/net/* files on each run. Turns out you can just
keep then open and seek to the beginning and reread and the contents
are fresh.

    name                    old time/op    new time/op    delta
    GetListIncremental-8    7.29ms ± 2%    6.53ms ± 1%  -10.50%  (p=0.000 n=9+9)

    name                   old alloc/op   new alloc/op   delta
    GetListIncremental-8    1.30kB ±13%    0.70kB ± 5%  -46.38%  (p=0.000 n=9+10)

    name                  old allocs/op  new allocs/op  delta
    GetListIncremental-8      33.2 ±11%      18.0 ± 0%  -45.82%  (p=0.000 n=9+10)

Updates #5958

Change-Id: I4be83463cbd23c2e2fa5d0bdf38560004f53401b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 7149155b80 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>
2 years ago
Brad Fitzpatrick 46ce80758d portlist: update some internals to use append-style APIs
In prep for reducing garbage, being able to reuse memory.  So far this
doesn't actually reuse much. This is just changing signatures around.

But some improvement in any case:

    bradfitz@tsdev:~/src/tailscale.com$ ~/go/bin/benchstat before after
    name       old time/op    new time/op    delta
    GetList-8    11.8ms ± 9%     9.9ms ± 3%  -15.98%  (p=0.000 n=10+10)

    name       old alloc/op   new alloc/op   delta
    GetList-8    99.5kB ± 2%    91.9kB ± 0%   -7.62%  (p=0.000 n=9+9)

    name       old allocs/op  new allocs/op  delta
    GetList-8     3.05k ± 1%     2.93k ± 0%   -3.83%  (p=0.000 n=8+9)

More later, once parsers can reuse strings from previous parses.

Updates #5958

Change-Id: I76cd5048246dd24d11c4e263d8bb8041747fb2b0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 61f201f33d portlist: reuse bufio.Reader between files
name         old time/op    new time/op    delta
ListPorts-6    1.18ms ± 5%    1.16ms ± 5%     ~     (p=0.075 n=10+10)

name         old alloc/op   new alloc/op   delta
ListPorts-6    27.2kB ± 0%    14.9kB ± 0%  -45.14%  (p=0.001 n=8+9)

name         old allocs/op  new allocs/op  delta
ListPorts-6      90.0 ± 0%      84.0 ± 0%   -6.67%  (p=0.000 n=10+10)

Updates tailscale/corp#2566

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 5a9d977c78 portlist: reduce CPU parsing portlist
Avoid splitting fields in the common case. Field splitting was 84% of
the overall CPU.

name          old time/op    new time/op    delta
ParsePorts-6    33.3ms ± 2%     6.3ms ± 4%  -80.97%  (p=0.000 n=9+10)

name          old alloc/op   new alloc/op   delta
ParsePorts-6      520B ±79%      408B ± 0%  -21.49%  (p=0.046 n=10+8)

name          old allocs/op  new allocs/op  delta
ParsePorts-6      7.00 ± 0%      7.00 ± 0%     ~     (all equal)

Updates tailscale/corp#2566

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
Brad Fitzpatrick 64e9ce8df1 portlist: reduce allocs on Linux
Notably, it no longer allocates proportional to the number of open
sockets on the machine. Any alloc reduction numbers are a little
contrived with such a reduction but e.g. on a machine with 50,000
connections open:

name          old time/op    new time/op    delta
ParsePorts-6    57.7ms ± 6%    32.8ms ± 3%   -43.04%  (p=0.000 n=9+10)

name          old alloc/op   new alloc/op   delta
ParsePorts-6    24.0MB ± 0%     0.0MB ± 0%  -100.00%  (p=0.000 n=10+9)

name          old allocs/op  new allocs/op  delta
ParsePorts-6      100k ± 0%        0k ± 0%   -99.99%  (p=0.000 n=10+10)

Updates tailscale/corp#2566

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
David Anderson 63a9adeb6c portlist: collect IPv6 listening sockets on linux.
This is important because some of those v6 sockets are actually
dual-stacked sockets, so this is our only chance of discovering
some services.

Fixes #1443.

Signed-off-by: David Anderson <danderson@tailscale.com>
4 years ago