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.
Goals
We've witnessed high CPU usage in UnverifiedBlockStore.PruneBlocks in the wild. Prune blocks is used to make sure that blocks received from a remote peer for a traversal do not accumulate in memory. This happens at two points:
The problem here is that when we do #1, which is run after every message received, we currently loop through all blocks in the store -- meaning that if they were part of a previous message and didn't get pruned cause they were referenced in metadata, but the selector traversal hasn't caught up and removed the block from the store, we still iterate over them blocks.
Implementation
For pruning step 1, instead of iterating over all blocks, iterate only over those blocks that were part of the message we just processed. Any other blocks are either already pruned or they wouldn't get pruned in this step. You can think of it as a very very basic kind of generational GC -- we only see if we can garbage collect the most recent stuff, and we're luck enough to know the exact rules around whether we can garbage collect them.
This results in removing this CPU bottleneck by drastically shortening this map iteration:
Pre-CPU-profile:
Post-CPU-profile: (not UnverifiedBlockStore.PruneBlocks gone as a hot spot)