[llvm] fffe272 - [ADT] Make set_subtract more efficient when subtrahend is larger (NFC) (#98702)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 17 13:53:15 PDT 2024


Author: Teresa Johnson
Date: 2024-07-17T13:53:10-07:00
New Revision: fffe2728534a238ff0024e11a18280f85094dcde

URL: https://github.com/llvm/llvm-project/commit/fffe2728534a238ff0024e11a18280f85094dcde
DIFF: https://github.com/llvm/llvm-project/commit/fffe2728534a238ff0024e11a18280f85094dcde.diff

LOG: [ADT] Make set_subtract more efficient when subtrahend is larger (NFC) (#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.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/SetOperations.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/SetOperations.h b/llvm/include/llvm/ADT/SetOperations.h
index 1a911b239f4c6..ba784bddfe79a 100644
--- a/llvm/include/llvm/ADT/SetOperations.h
+++ b/llvm/include/llvm/ADT/SetOperations.h
@@ -94,7 +94,22 @@ S1Ty set_
diff erence(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);


        


More information about the llvm-commits mailing list