Skip to content

Optimize by pre allocate slices to avoid Runtime.Growslice #15261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

terencechain
Copy link
Collaborator

I've fixed the top 5 offenders given the following profile.
(s *SignatureBatch) Join is the worst one.
Screenshot 2025-05-09 at 11 03 56 AM

@@ -265,7 +265,9 @@ func (s *Service) hasSeenAggregatorIndexEpoch(epoch primitives.Epoch, aggregator
func (s *Service) setAggregatorIndexEpochSeen(epoch primitives.Epoch, aggregatorIndex primitives.ValidatorIndex) {
s.seenAggregatedAttestationLock.Lock()
defer s.seenAggregatedAttestationLock.Unlock()
b := append(bytesutil.Bytes32(uint64(epoch)), bytesutil.Bytes32(uint64(aggregatorIndex))...)
b := make([]byte, 64)
copy(b[0:32], bytesutil.Bytes32(uint64(epoch)))
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume this code was previously calling Bytes32 for padding, but since you are already pre-allocating the slice, couldn't you just call copy directly (knowing that the pre-allocated bytes are already zero)? That should save you a couple more allocations right?


b := make([]byte, 64)
binary.BigEndian.PutUint64(b[24:], uint64(epoch))
binary.BigEndian.PutUint64(b[56:], uint64(aggregatorIndex))
Copy link
Contributor

Choose a reason for hiding this comment

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

These slices offsets look wrong, and it seems like this is changing the encoding from LittleEndian to BigEndian? I think it should be:

	b := make([]byte, 64)
	binary.LittleEndian.PutUint64(b, uint64(epoch))
	binary.LittleEndian.PutUint64(b[32:], uint64(aggregatorIndex))


total := len(s.Signatures) + len(set.Signatures)

if cap(s.Signatures) < total {
Copy link
Contributor

Choose a reason for hiding this comment

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

re this updated version - to get the amortization benefit you want to straight up append, which will let the go runtime do its default behavior of allocating cap()*2. So if you want to go this way, you can just get rid of lines 40-61.

kasey
kasey previously approved these changes May 9, 2025
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