Skip to content
7 changes: 7 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Bolt's Performance Journal

Critical learnings and performance patterns discovered in this codebase.

## 2026-08-08 - Pre-parse IP Addresses for Comparator Functions
**Learning:** `sort.Slice` calls comparator functions $O(N \log N)$ times. Calling `netip.ParseAddr` or other parsing/conversion functions inside a sort comparator creates severe CPU overhead ($2 \cdot N \log_2 N$ string parses) during large discovery sweeps (up to 65,536 hosts).
**Action:** Always pre-parse IP strings into `netip.Addr` structs once into a temporary slice or wrapper struct before sorting.
56 changes: 44 additions & 12 deletions pkg/proxy/discovery/sweep.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package discovery

import (
"cmp"
"context"
"fmt"
"net"
"net/netip"
"sort"
"slices"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -141,11 +142,7 @@ func runSweep(ctx context.Context, cfg sweepConfig) (*SweepResult, error) {
enrichFromARP(hosts)
enrichRDNS(ctx, hosts)

out := make([]SweepHost, 0, len(hosts))
for _, h := range hosts {
out = append(out, *h)
}
sort.Slice(out, func(i, j int) bool { return compareIPs(out[i].IP, out[j].IP) })
out := sortHosts(hosts)

cidrStrings := make([]string, len(cfg.cidrs))
for i, c := range cfg.cidrs {
Expand Down Expand Up @@ -272,13 +269,48 @@ func trimTrailingDot(s string) string {
return s
}

Comment thread
blue4209211 marked this conversation as resolved.
func compareIPs(a, b string) bool {
aa, errA := netip.ParseAddr(a)
bb, errB := netip.ParseAddr(b)
if errA != nil || errB != nil {
return a < b
// sortHosts converts the host map into an IP-sorted slice of SweepHost.
// Pre-parses IP addresses once into netip.Addr to avoid O(N log N) string parses in sort comparator.
// Stores pointers (*SweepHost) to keep sweepHostAddr small (32 bytes) and avoid struct copying overhead.
func sortHosts(hosts map[string]*SweepHost) []SweepHost {
type sweepHostAddr struct {
host *SweepHost
addr netip.Addr
}
items := make([]sweepHostAddr, 0, len(hosts))
for _, h := range hosts {
if h == nil {
continue
}
// A parse failure yields the zero Addr, which reports IsValid() == false,
// so the comparator below can sort unparseable IPs to the end without
// branching on the error here.
addr, _ := netip.ParseAddr(h.IP)
items = append(items, sweepHostAddr{host: h, addr: addr})
}
// slices.SortFunc avoids the reflection and interface boxing that sort.Slice
// pays on every comparison.
slices.SortFunc(items, func(a, b sweepHostAddr) int {
aValid := a.addr.IsValid()
bValid := b.addr.IsValid()
if aValid != bValid {
// Unparseable IPs sort to the end.
if aValid {
return -1
}
return 1
}
if !aValid {
return cmp.Compare(a.host.IP, b.host.IP)
}
return a.addr.Compare(b.addr)
})

out := make([]SweepHost, len(items))
for i, item := range items {
out[i] = *item.host
}
return aa.Less(bb)
return out
}

// parseSweepParams validates an action's parameters and clamps them to the
Expand Down
52 changes: 52 additions & 0 deletions pkg/proxy/discovery/sweep_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package discovery
import (
"context"
"encoding/json"
"fmt"
"net"
"net/netip"
"sync/atomic"
Expand Down Expand Up @@ -453,3 +454,54 @@ func TestRunSweep_MoreWorkersDoNotExceedRateCap(t *testing.T) {
cfg.workers, result.Scanned, elapsed, ratePPS, minDuration)
}
}

func BenchmarkSweepResultSorting(b *testing.B) {
hosts := make(map[string]*SweepHost, 1000)
for i := 0; i < 1000; i++ {
ip := fmt.Sprintf("10.0.%d.%d", i/256, i%256)
hosts[ip] = &SweepHost{IP: ip}
}

b.ResetTimer()
for n := 0; n < b.N; n++ {
_ = sortHosts(hosts)
}
}

func TestSortHosts_HandlesNilHostPointers(t *testing.T) {
hosts := map[string]*SweepHost{
"10.0.0.2": {IP: "10.0.0.2"},
"10.0.0.1": nil,
"10.0.0.3": {IP: "10.0.0.3"},
}

sorted := sortHosts(hosts)
if len(sorted) != 2 {
t.Fatalf("expected 2 non-nil hosts, got %d", len(sorted))
}
if sorted[0].IP != "10.0.0.2" || sorted[1].IP != "10.0.0.3" {
t.Errorf("unexpected sorted IPs: %v", sorted)
}
}
Comment thread
blue4209211 marked this conversation as resolved.

func TestSortHosts_UnparseableIPsSortLast(t *testing.T) {
hosts := map[string]*SweepHost{
"10.0.0.2": {IP: "10.0.0.2"},
"10.0.0.1": nil,
"invalid-ip-b": {IP: "invalid-ip-b"},
"10.0.0.10": {IP: "10.0.0.10"},
"invalid-ip-a": {IP: "invalid-ip-a"},
}

sorted := sortHosts(hosts)
// Valid IPs first in numeric order, then unparseable ones lexicographically.
want := []string{"10.0.0.2", "10.0.0.10", "invalid-ip-a", "invalid-ip-b"}
if len(sorted) != len(want) {
t.Fatalf("expected %d non-nil hosts, got %d", len(want), len(sorted))
}
for i, exp := range want {
if sorted[i].IP != exp {
t.Errorf("at index %d: want %q, got %q", i, exp, sorted[i].IP)
}
}
}
Loading