Bug 1552712 - Reserve capacity in IntervalSet::Intersection(). r=jya

Profiling shows we can spend a lot of time in IntervalSet::Intersection().

Much of this time is spent appending elements to a temporary buffer as we
loop over the two IntervalSets' arrays comparing them. As we append, the
storage of the temporary array is reallocated as the storage must grow to
hold more elements. These reallocations are expensive, as we must copy the
old elements to the new storage.

So before starting the loop, reserve enough capacity to store the upper
bound; the minimum of the two IntervalSets' lengths. This may waste memory,
but will be faster, as expensive reallocations are avoided.

Differential Revision: https://phabricator.services.mozilla.com/D31744

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Chris Pearce 2019-05-21 02:09:18 +00:00
parent 0383d9bf4e
commit 922077eefe

View File

@ -428,6 +428,11 @@ class IntervalSet {
SelfType& Intersection(const SelfType& aOther) {
ContainerType intersection;
// Ensure the intersection has enough capacity to store the upper bound on
// the intersection size. This ensures that we don't spend time reallocating
// the storage as we append, at the expense of extra memory.
intersection.SetCapacity(std::min(aOther.Length(), mIntervals.Length()));
const ContainerType& other = aOther.mIntervals;
IndexType i = 0, j = 0;
for (; i < mIntervals.Length() && j < other.Length();) {
@ -440,8 +445,7 @@ class IntervalSet {
j++;
}
}
mIntervals.Clear();
mIntervals.AppendElements(std::move(intersection));
mIntervals = std::move(intersection);
return *this;
}