Unique code-completion strings. On Cocoa.h, this costs us about 4% in

speed but saves us about 25% of the memory usage for strings.

llvm-svn: 124704
This commit is contained in:
Douglas Gregor 2011-02-01 23:59:42 +00:00
parent 0917d6e5d5
commit 801acff462
2 changed files with 69 additions and 0 deletions

View File

@ -15,7 +15,9 @@
#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "clang-c/Index.h"
@ -421,11 +423,47 @@ public:
std::string getAsString() const;
};
/// \brief \c DenseMap information object for StringRefs.
struct DenseMapStringRefInfo {
static inline llvm::StringRef getEmptyKey() {
return llvm::StringRef(reinterpret_cast<const char*>((intptr_t)-1), 0);
}
static inline llvm::StringRef getTombstoneKey() {
return llvm::StringRef(reinterpret_cast<const char *>((intptr_t)-2), 0);
}
static unsigned getHashValue(llvm::StringRef Str) {
return llvm::HashString(Str);
}
static bool isEqual(llvm::StringRef LHS, llvm::StringRef RHS) {
if (LHS.size() == 0 && RHS.size() == 0) {
intptr_t LHSVal = reinterpret_cast<intptr_t>(LHS.data());
intptr_t RHSVal = reinterpret_cast<intptr_t>(RHS.data());
if (LHSVal == -1 || LHSVal == -2 || RHSVal == -1 || RHSVal == -2)
return LHSVal == RHSVal;
return true;
}
return LHS == RHS;
}
};
/// \brief An allocator used specifically for the purpose of code completion.
class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
llvm::DenseSet<llvm::StringRef, DenseMapStringRefInfo> UniqueStrings;
unsigned StringBytesAllocated;
unsigned StringBytesUniqued;
unsigned StringsAllocated;
unsigned StringsUniqued;
public:
CodeCompletionAllocator();
~CodeCompletionAllocator();
/// \brief Copy the given string into this allocator.
const char *CopyString(llvm::StringRef String);
void PrintStats();
};
/// \brief A builder class used to construct new code-completion strings.

View File

@ -220,10 +220,41 @@ const char *CodeCompletionString::getTypedText() const {
return 0;
}
CodeCompletionAllocator::CodeCompletionAllocator()
: llvm::BumpPtrAllocator(), StringBytesAllocated(0), StringBytesUniqued(0),
StringsAllocated(0), StringsUniqued(0)
{
}
CodeCompletionAllocator::~CodeCompletionAllocator() { }
void CodeCompletionAllocator::PrintStats() {
llvm::errs() << "---Code completion memory allocation---\n"
<< "String bytes uniqued: " << StringBytesUniqued << "/"
<< StringBytesAllocated << " ("
<< ((float)StringBytesUniqued*100/StringBytesAllocated)
<< ")\nStrings uniqued: " << StringsUniqued << "/" << StringsAllocated
<< " (" << ((float)StringsUniqued*100/StringsAllocated)
<< ")\n";
llvm::BumpPtrAllocator::PrintStats();
}
const char *CodeCompletionAllocator::CopyString(llvm::StringRef String) {
llvm::DenseSet<llvm::StringRef, DenseMapStringRefInfo>::iterator Uniqued
= UniqueStrings.find(String);
++StringsAllocated;
StringBytesAllocated += String.size() + 1;
if (Uniqued != UniqueStrings.end()) {
StringBytesUniqued += String.size() + 1;
++StringsUniqued;
return Uniqued->data();
}
char *Mem = (char *)Allocate(String.size() + 1, 1);
std::copy(String.begin(), String.end(), Mem);
Mem[String.size()] = 0;
UniqueStrings.insert(llvm::StringRef(Mem, String.size()));
return Mem;
}