[Efficiency Improver] perf(auth): eliminate per-IP heap allocation in RateLimiter#582
Draft
github-actions[bot] wants to merge 1 commit into
Draft
Conversation
Replace map[string]*visitor with map[string]visitor to eliminate one heap allocation per unique IP address tracked by the rate limiter. Before: each new visitor entry allocated a *visitor on the heap (32-byte struct + 8-byte GC-tracked pointer in the map). After: visitor state is stored inline in the map bucket. New visitor entries no longer require a separate heap allocation, reducing GC pressure proportionally to the number of unique IPs tracked. The denial path is simplified: a single write-back captures both the lastSeen update and the conditional token decrement, removing the need for two separate control-flow return points. Benchmarks to verify improvement: go test -bench=BenchmarkRateLimiterAllow -benchmem ./auth/ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 This is a draft PR from Weekly Efficiency Improver, an automated AI assistant focused on reducing energy consumption.
Goal and Rationale
Every unique IP address processed by
RateLimiterpreviously required a separate heap allocation for itsvisitorstruct. At scale (e.g. 10 k req/s from diverse IPs), this meant thousands of small allocations per second, increasing GC frequency and CPU energy draw.Focus area: Code-Level Efficiency — Memory allocation reduction
Approach
Changed
visitors map[string]*visitor→visitors map[string]visitorso visitor state is stored inline in the map bucket, eliminating the per-entry pointer indirection and the corresponding heap allocation.The denial path was also simplified: a single
rl.visitors[key] = vwrite-back captures both thelastSeenupdate and the conditional token decrement, removing two separatereturnpoints.New benchmarks are added to quantify the improvement and guard against future regressions:
Energy Efficiency Evidence
Proxy metric used: Heap allocations per operation (direct proxy for GC CPU overhead and DRAM energy).
*visitoron heap)Baseline estimated from code inspection; CI benchmarks (
-benchmem) will produce exact numbers.Why this maps to energy: Each heap allocation requires the GC to track the pointer, scan it at collection time, and eventually free it. Eliminating N allocations/second removes that GC overhead proportional to N, reducing idle CPU cycles — directly lowering power draw per request.
Memory layout improvement (cache locality): With the pointer map, accessing a visitor's fields required chasing a pointer to a separate heap object (potential cache miss). With the value map, visitor fields are co-located with the map bucket (likely already hot in L1/L2 cache).
Green Software Foundation Context
Trade-offs
rl.visitors[key] = v). The existing mutex already serialises all access, so this adds no correctness risk.visitorvalues instead of 8-byte pointers. For the default max of 10,000 visitors, total map memory actually decreases from ~400 KB (10k × 40 bytes: 8-byte pointer + 32-byte heap struct) to ~320 KB (10k × 32 bytes inline).visitoris unexported; all public types and interfaces are unchanged.Test Status
Tests verified structurally correct by code inspection (logic unchanged). CI will run the full test suite with Go 1.26.1.
Note: the local runner environment has Go 1.25.11, which is older than the go.mod requirement (1.26.1), so tests cannot be run locally — CI is the authoritative test gate.
Reproducibility
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
proxy.golang.orgSee Network Configuration for more information.
Add this agentic workflows to your repo
To install this agentic workflow, run