[Lldb-commits] [lldb] 3372284 - Use a SmallPtrSet rather than a SmallVector in ClusterManager.
Jim Ingham via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 18 09:34:37 PDT 2022
Author: Jim Ingham
Date: 2022-08-18T09:34:28-07:00
New Revision: 33722848fcb5b569ab3a388cae15f31acf9a9c5e
URL: https://github.com/llvm/llvm-project/commit/33722848fcb5b569ab3a388cae15f31acf9a9c5e
DIFF: https://github.com/llvm/llvm-project/commit/33722848fcb5b569ab3a388cae15f31acf9a9c5e.diff
LOG: Use a SmallPtrSet rather than a SmallVector in ClusterManager.
The m_objects store in this class is only used to check whether
this ClusterManager already owns this pointer. With a SmallVector
the is_contained call was non-linear in number of children, and for
instance printing all the elements of a 16M element std::vector
didn't complete in the time I was willing to wait for it (hours).
Since we are only doing insert & contains, some kind of set is a
better data structure. In this patch I used SmallPtrSet. With
that, the same array prints out in 30 seconds. I also tried a
std::unordered_set but that was slightly slower and used a fair bit
more memory.
Other than performance, this is NFC.
Differential Revision: https://reviews.llvm.org/D131996
Added:
Modified:
lldb/include/lldb/Utility/SharedCluster.h
Removed:
################################################################################
diff --git a/lldb/include/lldb/Utility/SharedCluster.h b/lldb/include/lldb/Utility/SharedCluster.h
index b3f41dbaa64b0..9f7aa92420ed0 100644
--- a/lldb/include/lldb/Utility/SharedCluster.h
+++ b/lldb/include/lldb/Utility/SharedCluster.h
@@ -11,7 +11,7 @@
#include "lldb/Utility/LLDBAssert.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include <memory>
#include <mutex>
@@ -32,15 +32,15 @@ class ClusterManager : public std::enable_shared_from_this<ClusterManager<T>> {
void ManageObject(T *new_object) {
std::lock_guard<std::mutex> guard(m_mutex);
- assert(!llvm::is_contained(m_objects, new_object) &&
- "ManageObject called twice for the same object?");
- m_objects.push_back(new_object);
+ auto ret = m_objects.insert(new_object);
+ assert(ret.second && "ManageObject called twice for the same object?");
}
std::shared_ptr<T> GetSharedPointer(T *desired_object) {
std::lock_guard<std::mutex> guard(m_mutex);
auto this_sp = this->shared_from_this();
- if (!llvm::is_contained(m_objects, desired_object)) {
+ size_t count = m_objects.count(desired_object);
+ if (count == 0) {
lldbassert(false && "object not found in shared cluster when expected");
desired_object = nullptr;
}
@@ -49,8 +49,14 @@ class ClusterManager : public std::enable_shared_from_this<ClusterManager<T>> {
private:
ClusterManager() : m_objects() {}
-
- llvm::SmallVector<T *, 16> m_objects;
+ // The cluster manager is used primarily to manage the
+ // children of root ValueObjects. So it will always have
+ // one element - the root. Pointers will often have dynamic
+ // values, so having 2 entries is pretty common. It's also
+ // pretty common to have small (2,3) structs, so setting the
+ // static size to 4 will cover those cases with no allocations
+ // w/o wasting too much space.
+ llvm::SmallPtrSet<T *, 4> m_objects;
std::mutex m_mutex;
};
More information about the lldb-commits
mailing list