Skip to content

Commit

Permalink
[ADT] Make set_subtract more efficient when subtrahend is larger (NFC…
Browse files Browse the repository at this point in the history
…) (#98702)

If the subtrahend is larger, iterate the minuend set instead.

Noticed when subtracting a large set from a number of other smaller
sets for an upcoming MemProf change, this change makes that much faster.

I subsequently found a couple of callsites in one file that were calling
set_subtract with a vector subtrahend, which doesn't have the "count()"
interface. Add a separate helper for subtracting a vector.
  • Loading branch information
teresajohnson authored Jul 17, 2024
1 parent 33cb29c commit fffe272
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions llvm/include/llvm/ADT/SetOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,22 @@ S1Ty set_difference(const S1Ty &S1, const S2Ty &S2) {

/// set_subtract(A, B) - Compute A := A - B
///
/// Selects the set to iterate based on the relative sizes of A and B for better
/// efficiency.
///
template <class S1Ty, class S2Ty> void set_subtract(S1Ty &S1, const S2Ty &S2) {
using ElemTy = decltype(*S1.begin());
// A couple callers pass a vector for S2, which doesn't support contains(),
// and wouldn't be efficient if it did.
if constexpr (detail::HasMemberContains<S2Ty, ElemTy>) {
if (S1.size() < S2.size()) {
for (typename S1Ty::iterator SI = S1.begin(), SE = S1.end(); SI != SE;
++SI)
if (S2.contains(*SI))
S1.erase(SI);
return;
}
}
for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end(); SI != SE;
++SI)
S1.erase(*SI);
Expand Down

0 comments on commit fffe272

Please sign in to comment.