diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 00000000..7a728351 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2025-01-23 - Stack Allocation for Temporary Buffers +**Learning:** Using `make([]byte, n)` for small, temporary buffers (like IP parsing) in hot loops causes significant allocation overhead. Replacing them with stack-allocated arrays (e.g., `var buf [16]byte; slice := buf[:]`) eliminates these allocations entirely. +**Action:** Look for small `make` calls in hot paths (especially in `proc` parsing) and replace them with stack buffers where the size is bounded and small. diff --git a/proc/net.go b/proc/net.go index 70d6039d..3ab42141 100644 --- a/proc/net.go +++ b/proc/net.go @@ -58,8 +58,7 @@ func readSockets(src string) ([]Sock, error) { local, b := nextField(b) remote, b := nextField(b) st, b := nextField(b) - state := string(st) - if state != stateEstablished && state != stateListen { + if string(st) != stateEstablished && string(st) != stateListen { continue } _, b = nextField(b) @@ -68,7 +67,7 @@ func readSockets(src string) ([]Sock, error) { _, b = nextField(b) _, b = nextField(b) inode, _ := nextField(b) - res = append(res, Sock{SAddr: decodeAddr(local), DAddr: decodeAddr(remote), Listen: state == stateListen, Inode: string(inode)}) + res = append(res, Sock{SAddr: decodeAddr(local), DAddr: decodeAddr(remote), Listen: string(st) == stateListen, Inode: string(inode)}) } return res, nil } @@ -93,11 +92,13 @@ func decodeAddr(src []byte) netaddr.IPPort { if col == -1 || (col != 8 && col != 32) { return netaddr.IPPort{} } - ip := make([]byte, col/2) + var ipBuf [16]byte + ip := ipBuf[:col/2] if _, err := hex.Decode(ip, src[:col]); err != nil { return netaddr.IPPort{} } - port := make([]byte, 2) + var portBuf [2]byte + port := portBuf[:] if _, err := hex.Decode(port, src[col+1:]); err != nil { return netaddr.IPPort{} }