Skip to content

Conversation

copybara-service[bot]
Copy link

Eliminate RepeatedPtrFieldBase::Rep::allocated_size: fix slow extending

Fixes the slowdown in the field mutations caused by memsetting newly added elements to nulls in RepeatedPtrField::InternalExtend():

  • Instead of memsetting the entire new array, sets only one or at most two sentinel elements to nulls.
  • The first sentinel immediately follows the last allocated (non-null) element, if there is an unallocated gap due to intentional overallocating in InternalExtend(). This is used to terminate several for-loops that previously relied on allocated_size(), and to reimplement allocated_size() (now AllocatedSize() because it's now slower and no longer trivial) for just a couple remaining places that still use the value.
  • The second sentinel is always the last unallocated element, just before Capacity(), also when there is an unallocated gap and possibly coinciding with the other sentinel if the gap is just 1 element. This sentinel is used to determine if the fuild has unallocated elements.
  • The methods that previously incremented or decremented allocated_size() now move the sentinels in the appropriate direction.

…ding

Fixes the slowdown in the field mutations caused by `memset`ting newly added elements to nulls in `RepeatedPtrField::InternalExtend()`:

* Instead of `memset`ting the entire new array, sets only one or at most two sentinel elements to nulls.
* The first sentinel immediately follows the last allocated (non-null) element, if there is an unallocated gap due to intentional overallocating in `InternalExtend()`. This is used to terminate several for-loops that previously relied on `allocated_size()`, and to reimplement `allocated_size()` (now `AllocatedSize()` because it's now slower and no longer trivial) for just a couple remaining places that still use the value.
* The second sentinel is always the last unallocated element, just before `Capacity()`, also when there is an unallocated gap and possibly coinciding with the other sentinel if the gap is just 1 element. This sentinel is used to determine if the fuild has unallocated elements.
* The methods that previously incremented or decremented `allocated_size()` now move the sentinels in the appropriate direction.

PiperOrigin-RevId: 814520734
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.

1 participant