Skip to content

⚡ Bolt: Zero-alloc optimization for proc/net decodeAddr#192

Closed
blue4209211 wants to merge 1 commit into
mainfrom
bolt/proc-net-zero-alloc-8121588879501371504
Closed

⚡ Bolt: Zero-alloc optimization for proc/net decodeAddr#192
blue4209211 wants to merge 1 commit into
mainfrom
bolt/proc-net-zero-alloc-8121588879501371504

Conversation

@blue4209211
Copy link
Copy Markdown
Contributor

⚡ Bolt: Zero-alloc optimization for proc/net decodeAddr

💡 What:
Replaced heap allocations (make([]byte, ...)) with stack-allocated arrays ([16]byte) in decodeAddr function.

🎯 Why:
The decodeAddr function is called for every socket in /proc/net/tcp* files. Allocating slices for IP and port on every call creates unnecessary GC pressure.

📊 Impact:

  • IPv4 decoding: ~40% faster (51ns -> 29ns)
  • IPv6 decoding: ~30% faster (91ns -> 61ns)
  • Allocations: Reduced from 1 alloc/op to 0 allocs/op.

🔬 Measurement:
Ran benchmarks in proc/bench_test.go (temporary file).
Before:
BenchmarkDecodeAddr/IPv4-4 22240496 51.88 ns/op 4 B/op 1 allocs/op
BenchmarkDecodeAddr/IPv6-4 12897699 91.40 ns/op 16 B/op 1 allocs/op

After:
BenchmarkDecodeAddr/IPv4-4 43319718 29.62 ns/op 0 B/op 0 allocs/op
BenchmarkDecodeAddr/IPv6-4 19834668 61.09 ns/op 0 B/op 0 allocs/op


PR created automatically by Jules for task 8121588879501371504 started by @blue4209211

Optimizes `decodeAddr` in `proc/net.go` to use stack-allocated arrays (`[16]byte`, `[2]byte`) instead of heap-allocated slices (`make([]byte, ...)`).

This eliminates memory allocations in the hot path of parsing `/proc/net/tcp` and `/proc/net/tcp6`.
Benchmarks show ~30-40% speedup and 0 allocations per op (down from 1 alloc/op).

Also removes unused `net` import.

Co-authored-by: blue4209211 <3078106+blue4209211@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @blue4209211, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a critical optimization to the decodeAddr function, which is frequently called when processing network information from /proc/net/tcp* files. By switching from heap-allocated slices to stack-allocated arrays for temporary buffers, the change aims to eliminate unnecessary garbage collection overhead and improve the overall performance of network address decoding, resulting in faster execution and zero allocations per operation.

Highlights

  • Zero-allocation optimization: The decodeAddr function in proc/net.go has been refactored to replace heap allocations (make([]byte, ...)) with stack-allocated arrays ([16]byte and [2]byte) for IP and port parsing.
  • Performance Improvement: This change significantly reduces garbage collection pressure, leading to a ~40% speed improvement for IPv4 decoding (51ns to 29ns) and ~30% for IPv6 decoding (91ns to 61ns), with allocations reduced from 1 alloc/op to 0 allocs/op.
  • Code Simplification: The net package import was removed, and IP address construction now directly uses netaddr.IPv4 or netaddr.IPFrom16 based on the address type, streamlining the logic.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant performance optimization to the decodeAddr function by eliminating heap allocations. The change replaces make([]byte, ...) with stack-allocated arrays for parsing IP addresses and ports, which is a great improvement for this hot path. The logic is sound and the performance benefits are clearly documented. I have one minor suggestion to improve the readability and potentially the performance of the byte-swapping logic.

Comment thread proc/net.go
Comment on lines 106 to 110
var v uint32
for i := 0; i < len(ip); i += 4 {
for i := 0; i < col/2; i += 4 {
v = binary.BigEndian.Uint32(ip[i : i+4])
binary.LittleEndian.PutUint32(ip[i:i+4], v)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For clarity and potentially a minor performance improvement, you can perform the byte-swapping directly. This makes the 4-byte reversal explicit and removes the need for the temporary variable v.

Suggested change
var v uint32
for i := 0; i < len(ip); i += 4 {
for i := 0; i < col/2; i += 4 {
v = binary.BigEndian.Uint32(ip[i : i+4])
binary.LittleEndian.PutUint32(ip[i:i+4], v)
}
// The IP address in /proc/net/tcp* is in little-endian format for each 32-bit word.
// We need to swap the byte order of each word to get the standard big-endian representation.
for i := 0; i < col/2; i += 4 {
ip[i], ip[i+1], ip[i+2], ip[i+3] = ip[i+3], ip[i+2], ip[i+1], ip[i]
}

@mayankpande88
Copy link
Copy Markdown
Contributor

Closing — superseded by newer PRs (#196 for eBPF parsing, #194 for proc/net optimization).

@mayankpande88 mayankpande88 deleted the bolt/proc-net-zero-alloc-8121588879501371504 branch May 27, 2026 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants