forked from OSchip/llvm-project
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
This commit is contained in:
parent
dd8982d44a
commit
33722848fc
|
@ -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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue