Skip to content

Commit 5ab84ae

Browse files
committed
[CodeCompletion] Precompute and cache "filter name"
Filter name for completion item is always used. Also, for cached items, they are used multiple times for filtering. So precomputing and caching it improves performance. rdar://84036006
1 parent 33ee4d6 commit 5ab84ae

File tree

9 files changed

+86
-89
lines changed

9 files changed

+86
-89
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ class ContextFreeCodeCompletionResult {
735735
static_assert(int(CodeCompletionDiagnosticSeverity::MAX_VALUE) < 1 << 3, "");
736736

737737
StringRef DiagnosticMessage;
738+
StringRef FilterName;
738739

739740
public:
740741
/// Memberwise initializer. \p AssociatedKInd is opaque and will be
@@ -753,13 +754,13 @@ class ContextFreeCodeCompletionResult {
753754
CodeCompletionResultType ResultType,
754755
ContextFreeNotRecommendedReason NotRecommended,
755756
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
756-
StringRef DiagnosticMessage)
757+
StringRef DiagnosticMessage, StringRef FilterName)
757758
: Kind(Kind), KnownOperatorKind(KnownOperatorKind), IsSystem(IsSystem),
758759
CompletionString(CompletionString), ModuleName(ModuleName),
759760
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
760761
ResultType(ResultType), NotRecommended(NotRecommended),
761762
DiagnosticSeverity(DiagnosticSeverity),
762-
DiagnosticMessage(DiagnosticMessage) {
763+
DiagnosticMessage(DiagnosticMessage), FilterName(FilterName) {
763764
this->AssociatedKind.Opaque = AssociatedKind;
764765
assert((NotRecommended == ContextFreeNotRecommendedReason::None) ==
765766
(DiagnosticSeverity == CodeCompletionDiagnosticSeverity::None) &&
@@ -869,7 +870,9 @@ class ContextFreeCodeCompletionResult {
869870
CodeCompletionDiagnosticSeverity getDiagnosticSeverity() const {
870871
return DiagnosticSeverity;
871872
}
872-
StringRef getDiagnosticMessage() const { return DiagnosticMessage; };
873+
StringRef getDiagnosticMessage() const { return DiagnosticMessage; }
874+
875+
StringRef getFilterName() const { return FilterName; }
873876

874877
bool isOperator() const {
875878
if (getKind() == CodeCompletionResultKind::Declaration) {
@@ -1110,6 +1113,10 @@ class CodeCompletionResult {
11101113
}
11111114
}
11121115

1116+
StringRef getFilterName() const {
1117+
return getContextFreeResult().getFilterName();
1118+
}
1119+
11131120
/// Print a debug representation of the code completion result to \p OS.
11141121
void printPrefix(raw_ostream &OS) const;
11151122
SWIFT_DEBUG_DUMP;

include/swift/IDE/CodeCompletionResultPrinter.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@
1313
#ifndef SWIFT_IDE_CODECOMPLETIONRESULTPRINTER_H
1414
#define SWIFT_IDE_CODECOMPLETIONRESULTPRINTER_H
1515

16+
#include "llvm/ADT/StringRef.h"
1617
#include "llvm/Support/raw_ostream.h"
18+
#include "llvm/Support/Allocator.h"
1719

1820
namespace swift {
1921
namespace ide {
2022

2123
class CodeCompletionResult;
24+
class CodeCompletionString;
2225

2326
void printCodeCompletionResultDescription(const CodeCompletionResult &Result,
2427
llvm::raw_ostream &OS,
@@ -37,8 +40,10 @@ void printCodeCompletionResultTypeNameAnnotated(
3740
void printCodeCompletionResultSourceText(
3841
const CodeCompletionResult &Result, llvm::raw_ostream &OS);
3942

40-
void printCodeCompletionResultFilterName(
41-
const CodeCompletionResult &Result, llvm::raw_ostream &OS);
43+
/// Print 'FilterName' from \p str into memory managed by \p Allocator and
44+
/// return it.
45+
llvm::StringRef getCodeCompletionResultFilterName(
46+
const CodeCompletionString *Str, llvm::BumpPtrAllocator &Allocator);
4247

4348
} // namespace ide
4449
} // namespace swift

lib/IDE/CodeCompletion.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ ContextFreeCodeCompletionResult::createPatternOrBuiltInOperatorResult(
336336
Kind, /*AssociatedKind=*/0, KnownOperatorKind,
337337
/*IsSystem=*/false, CompletionString, /*ModuleName=*/"", BriefDocComment,
338338
/*AssociatedUSRs=*/{}, ResultType, NotRecommended, DiagnosticSeverity,
339-
DiagnosticMessage);
339+
DiagnosticMessage,
340+
getCodeCompletionResultFilterName(CompletionString, Allocator));
340341
}
341342

342343
ContextFreeCodeCompletionResult *
@@ -350,7 +351,8 @@ ContextFreeCodeCompletionResult::createKeywordResult(
350351

351352
/*ModuleName=*/"", BriefDocComment,
352353
/*AssociatedUSRs=*/{}, ResultType, ContextFreeNotRecommendedReason::None,
353-
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"");
354+
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"",
355+
getCodeCompletionResultFilterName(CompletionString, Allocator));
354356
}
355357

356358
ContextFreeCodeCompletionResult *
@@ -364,7 +366,8 @@ ContextFreeCodeCompletionResult::createLiteralResult(
364366
/*IsSystem=*/false, CompletionString, /*ModuleName=*/"",
365367
/*BriefDocComment=*/"",
366368
/*AssociatedUSRs=*/{}, ResultType, ContextFreeNotRecommendedReason::None,
367-
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"");
369+
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"",
370+
getCodeCompletionResultFilterName(CompletionString, Allocator));
368371
}
369372

370373
ContextFreeCodeCompletionResult *
@@ -381,7 +384,8 @@ ContextFreeCodeCompletionResult::createDeclResult(
381384
static_cast<uint8_t>(getCodeCompletionDeclKind(AssociatedDecl)),
382385
CodeCompletionOperatorKind::None, getDeclIsSystem(AssociatedDecl),
383386
CompletionString, ModuleName, BriefDocComment, AssociatedUSRs, ResultType,
384-
NotRecommended, DiagnosticSeverity, DiagnosticMessage);
387+
NotRecommended, DiagnosticSeverity, DiagnosticMessage,
388+
getCodeCompletionResultFilterName(CompletionString, Allocator));
385389
}
386390

387391
CodeCompletionDeclKind
@@ -1488,36 +1492,18 @@ CodeCompletionContext::sortCompletionResults(
14881492
ArrayRef<CodeCompletionResult *> Results) {
14891493
std::vector<CodeCompletionResult *> SortedResults(Results.begin(),
14901494
Results.end());
1491-
struct ResultAndName {
1492-
CodeCompletionResult *result;
1493-
std::string name;
1494-
};
14951495

1496-
// Caching the name of each field is important to avoid unnecessary calls to
1497-
// CodeCompletionString::getName().
1498-
std::vector<ResultAndName> nameCache(SortedResults.size());
1499-
for (unsigned i = 0, n = SortedResults.size(); i < n; ++i) {
1500-
auto *result = SortedResults[i];
1501-
nameCache[i].result = result;
1502-
llvm::raw_string_ostream OS(nameCache[i].name);
1503-
printCodeCompletionResultFilterName(*result, OS);
1504-
OS.flush();
1505-
}
1506-
1507-
// Sort nameCache, and then transform SortedResults to return the pointers in
1508-
// order.
1509-
std::sort(nameCache.begin(), nameCache.end(),
1510-
[](const ResultAndName &LHS, const ResultAndName &RHS) {
1511-
int Result = StringRef(LHS.name).compare_insensitive(RHS.name);
1496+
std::sort(SortedResults.begin(), SortedResults.end(),
1497+
[](const auto &LHS, const auto &RHS) {
1498+
int Result = StringRef(LHS->getFilterName())
1499+
.compare_insensitive(RHS->getFilterName());
15121500
// If the case insensitive comparison is equal, then secondary
15131501
// sort order should be case sensitive.
15141502
if (Result == 0)
1515-
Result = LHS.name.compare(RHS.name);
1503+
Result = LHS->getFilterName().compare(RHS->getFilterName());
15161504
return Result < 0;
15171505
});
15181506

1519-
llvm::transform(nameCache, SortedResults.begin(),
1520-
[](const ResultAndName &entry) { return entry.result; });
15211507
return SortedResults;
15221508
}
15231509

lib/IDE/CodeCompletionCache.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ CodeCompletionCache::~CodeCompletionCache() {}
102102
///
103103
/// This should be incremented any time we commit a change to the format of the
104104
/// cached results. This isn't expected to change very often.
105-
static constexpr uint32_t onDiskCompletionCacheVersion = 4; // Store ContextFreeCodeCompletionResults in cache
105+
static constexpr uint32_t onDiskCompletionCacheVersion = 5; // Store FilterName in cache
106106

107107
/// Deserializes CodeCompletionResults from \p in and stores them in \p V.
108108
/// \see writeCacheModule.
@@ -209,6 +209,7 @@ static bool readCachedModule(llvm::MemoryBuffer *in,
209209
auto moduleIndex = read32le(cursor);
210210
auto briefDocIndex = read32le(cursor);
211211
auto diagMessageIndex = read32le(cursor);
212+
auto filterNameIndex = read32le(cursor);
212213

213214
auto assocUSRCount = read32le(cursor);
214215
SmallVector<StringRef, 4> assocUSRs;
@@ -220,14 +221,15 @@ static bool readCachedModule(llvm::MemoryBuffer *in,
220221
auto moduleName = getString(moduleIndex);
221222
auto briefDocComment = getString(briefDocIndex);
222223
auto diagMessage = getString(diagMessageIndex);
224+
auto filterName = getString(filterNameIndex);
223225

224226
ContextFreeCodeCompletionResult *result =
225227
new (*V.Allocator) ContextFreeCodeCompletionResult(
226228
kind, associatedKind, opKind, isSystem, string, moduleName,
227229
briefDocComment,
228230
copyArray(*V.Allocator, ArrayRef<StringRef>(assocUSRs)),
229231
CodeCompletionResultType::unknown(), notRecommended, diagSeverity,
230-
diagMessage);
232+
diagMessage, filterName);
231233

232234
V.Results.push_back(result);
233235
}
@@ -352,6 +354,7 @@ static void writeCachedModule(llvm::raw_ostream &out,
352354
LE.write(addString(R->getModuleName())); // index into strings
353355
LE.write(addString(R->getBriefDocComment())); // index into strings
354356
LE.write(addString(R->getDiagnosticMessage())); // index into strings
357+
LE.write(addString(R->getFilterName())); // index into strings
355358

356359
LE.write(static_cast<uint32_t>(R->getAssociatedUSRs().size()));
357360
for (unsigned i = 0; i < R->getAssociatedUSRs().size(); ++i) {

lib/IDE/CodeCompletionResultPrinter.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,8 @@ void swift::ide::printCodeCompletionResultSourceText(
450450
}
451451
}
452452

453-
void swift::ide::printCodeCompletionResultFilterName(
454-
const CodeCompletionResult &Result, llvm::raw_ostream &OS) {
455-
auto str = Result.getCompletionString();
453+
static void printCodeCompletionResultFilterName(
454+
const CodeCompletionString *str, llvm::raw_ostream &OS) {
456455
// FIXME: we need a more uniform way to handle operator completions.
457456
if (str->getChunks().size() == 1 && str->getChunks()[0].is(ChunkKind::Dot)) {
458457
OS << ".";
@@ -536,3 +535,15 @@ void swift::ide::printCodeCompletionResultFilterName(
536535
}
537536
}
538537
}
538+
539+
StringRef swift::ide::getCodeCompletionResultFilterName(
540+
const CodeCompletionString *Str, llvm::BumpPtrAllocator &Allocator) {
541+
SmallString<32> buf;
542+
llvm::raw_svector_ostream OS(buf);
543+
printCodeCompletionResultFilterName(Str, OS);
544+
size_t size = buf.size();
545+
char *storage = Allocator.Allocate<char>(size + 1);
546+
memcpy(storage, buf.data(), size);
547+
storage[size] = '\0';
548+
return {storage, size};
549+
}

tools/SourceKit/lib/SwiftLang/CodeCompletion.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,13 @@ class Completion {
9595
/// should outlive the result, generally by being stored in the same
9696
/// \c CompletionSink or in a sink that was adopted by the sink that this
9797
/// \c Compleiton is being stored in.
98-
Completion(const SwiftResult &base, StringRef name, StringRef description)
99-
: base(base), name(name), description(description) {}
98+
Completion(const SwiftResult &base, StringRef description)
99+
: base(base), description(description) {}
100100

101101
const SwiftResult &getSwiftResult() const { return base; }
102102

103103
bool hasCustomKind() const { return opaqueCustomKind; }
104104
void *getCustomKind() const { return opaqueCustomKind; }
105-
StringRef getName() const { return name; }
106105
StringRef getDescription() const { return description; }
107106
Optional<uint8_t> getModuleImportDepth() const { return moduleImportDepth; }
108107

@@ -166,6 +165,10 @@ class Completion {
166165
return getSwiftResult().getAssociatedUSRs();
167166
}
168167

168+
StringRef getFilterName() const {
169+
return getSwiftResult().getFilterName();
170+
}
171+
169172
/// Allow "upcasting" the completion result to a SwiftResult.
170173
operator const SwiftResult &() const { return getSwiftResult(); }
171174
};
@@ -194,7 +197,6 @@ class CompletionBuilder {
194197
SemanticContextKind semanticContext;
195198
CodeCompletionFlair flair;
196199
CodeCompletionString *completionString;
197-
llvm::SmallVector<char, 64> originalName;
198200
void *customKind = nullptr;
199201
Optional<uint8_t> moduleImportDepth;
200202
PopularityFactor popularityFactor;
@@ -223,7 +225,7 @@ class CompletionBuilder {
223225
void setPrefix(CodeCompletionString *prefix);
224226

225227
StringRef getOriginalName() const {
226-
return StringRef(originalName.begin(), originalName.size());
228+
return base.getFilterName();
227229
}
228230

229231
Completion *finish();

0 commit comments

Comments
 (0)