vpn: reduce throughputTracker per-tick allocations on mobile#498
Draft
garmr-ulfr wants to merge 1 commit into
Draft
vpn: reduce throughputTracker per-tick allocations on mobile#498garmr-ulfr wants to merge 1 commit into
garmr-ulfr wants to merge 1 commit into
Conversation
Heap profiling on the iOS extension showed throughputTracker.sample as the dominant cumulative allocator under traffic. Two changes: - Reuse the deltas, nextSeen, and nextPerOutbound maps across ticks via clear+swap instead of allocating fresh maps each second. - Default to a 3s sample interval on mobile. Each tick allocates a fresh snapshot slice of every live and recently-closed connection via the upstream trafficontrol API; at 1 Hz on a phone this dominated GC churn.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR optimizes VPN throughput tracking to reduce per-tick allocations/GC pressure (notably on mobile) by (1) selecting a longer default sampling interval on mobile platforms and (2) reusing scratch maps across sampling ticks instead of allocating new maps each tick.
Changes:
- Make the default throughput sampling interval platform-aware (3s on mobile, 1s elsewhere) via
common.IsMobile(). - Rework
throughputTracker.sample()to reuse and swap preallocated scratch maps (nextSeen,nextPerOutbound,deltas) to reduce allocations. - Update the Clash server wiring to pass
0as the interval so the tracker selects its default interval.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| vpn/throughput_tracker.go | Adds mobile-aware default interval and scratch-map reuse/swapping to reduce allocations per sampling tick. |
| vpn/clash.go | Removes now-unused time import and delegates tracker interval selection by passing 0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+23
to
+27
| var defaultThroughputSampleInterval = func() time.Duration { | ||
| if common.IsMobile() { | ||
| return 3 * time.Second | ||
| } | ||
| return time.Second |
Comment on lines
69
to
+72
| trafficManager: trafficManager, | ||
| throughputTracker: newThroughputTracker(trafficManager, time.Second), | ||
| modeList: modeList, | ||
| mode: initial, | ||
| throughputTracker: newThroughputTracker(trafficManager, 0), | ||
| modeList: modeList, | ||
| mode: initial, |
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 pull request introduces optimizations to the throughput tracking logic in the VPN package, primarily to reduce memory allocations and garbage collection overhead, especially on mobile devices. The changes dynamically adjust the throughput sampling interval based on the platform and introduce scratch maps that are reused across sampling ticks to minimize allocations.
Performance improvements for throughput tracking:
defaultThroughputSampleInterval) is now longer on mobile devices (3 seconds instead of 1 second) to reduce GC pressure caused by frequent allocations during heavy traffic. This is determined using the newcommon.IsMobile()check.throughputTrackerstruct now includes scratch maps (nextSeen,nextPerOutbound, anddeltas) that are reused across sampling ticks, avoiding repeated allocations and reducing GC churn. [1] [2]Refactoring of sampling logic:
samplemethod now clears and reuses the scratch maps instead of allocating new ones each tick. The method also swaps the maps after each sampling tick to maintain correct state while minimizing allocations. [1] [2]Other minor changes:
timepackage import was removed fromvpn/clash.goas it is no longer needed.newClashServerfunction now passes0for the throughput tracker interval, delegating the interval selection to the tracker itself.github.com/getlantern/radiance/commonto support platform detection.