Skip to content

Commit 73c201d

Browse files
committedSep 12, 2018
[clangd] Add index benchmarks
This patch introduces index benchmarks on top of the proposed LLVM benchmark pull. Reviewed By: sammccall, lebedev.ri Differential Revision: https://reviews.llvm.org/D51090 llvm-svn: 342026
1 parent e1e19c7 commit 73c201d

File tree

8 files changed

+160
-0
lines changed

8 files changed

+160
-0
lines changed
 

‎clang-tools-extra/clangd/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,7 @@ endif()
7575
add_subdirectory(tool)
7676
add_subdirectory(global-symbol-builder)
7777
add_subdirectory(index/dex/dexp)
78+
79+
if (LLVM_INCLUDE_BENCHMARKS)
80+
add_subdirectory(benchmarks)
81+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../)
2+
3+
add_benchmark(IndexBenchmark IndexBenchmark.cpp)
4+
5+
target_link_libraries(IndexBenchmark
6+
PRIVATE
7+
clangDaemon
8+
LLVMSupport
9+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===--- IndexBenchmark.cpp - Clangd index benchmarks -----------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "../index/SymbolYAML.h"
11+
#include "../index/dex/Dex.h"
12+
#include "benchmark/benchmark.h"
13+
#include "llvm/ADT/SmallVector.h"
14+
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/Support/Path.h"
16+
#include "llvm/Support/Regex.h"
17+
#include <fstream>
18+
#include <streambuf>
19+
#include <string>
20+
21+
const char *IndexFilename;
22+
const char *LogFilename;
23+
24+
namespace clang {
25+
namespace clangd {
26+
namespace {
27+
28+
std::unique_ptr<clang::clangd::SymbolIndex> buildMem() {
29+
return clang::clangd::loadIndex(IndexFilename, {}, false);
30+
}
31+
32+
std::unique_ptr<clang::clangd::SymbolIndex> buildDex() {
33+
return clang::clangd::loadIndex(IndexFilename, {}, true);
34+
}
35+
36+
// This function processes user-provided Log file with fuzzy find requests in
37+
// the following format:
38+
//
39+
// fuzzyFind("UnqualifiedName", scopes=["clang::", "clang::clangd::"])
40+
//
41+
// It constructs vector of FuzzyFindRequests which is later used for the
42+
// benchmarks.
43+
std::vector<clang::clangd::FuzzyFindRequest> extractQueriesFromLogs() {
44+
llvm::Regex RequestMatcher("fuzzyFind\\(\"([a-zA-Z]*)\", scopes=\\[(.*)\\]");
45+
llvm::SmallVector<llvm::StringRef, 200> Matches;
46+
std::ifstream InputStream(LogFilename);
47+
std::string Log((std::istreambuf_iterator<char>(InputStream)),
48+
std::istreambuf_iterator<char>());
49+
llvm::StringRef Temporary(Log);
50+
llvm::SmallVector<llvm::StringRef, 200> Strings;
51+
Temporary.split(Strings, '\n');
52+
53+
clang::clangd::FuzzyFindRequest R;
54+
R.MaxCandidateCount = 100;
55+
56+
llvm::SmallVector<llvm::StringRef, 200> CommaSeparatedValues;
57+
58+
std::vector<clang::clangd::FuzzyFindRequest> RealRequests;
59+
for (auto Line : Strings) {
60+
if (RequestMatcher.match(Line, &Matches)) {
61+
R.Query = Matches[1];
62+
CommaSeparatedValues.clear();
63+
Line.split(CommaSeparatedValues, ',');
64+
R.Scopes.clear();
65+
for (auto C : CommaSeparatedValues) {
66+
R.Scopes.push_back(C);
67+
}
68+
RealRequests.push_back(R);
69+
}
70+
}
71+
return RealRequests;
72+
}
73+
74+
static void MemQueries(benchmark::State &State) {
75+
const auto Mem = buildMem();
76+
const auto Requests = extractQueriesFromLogs();
77+
for (auto _ : State)
78+
for (const auto &Request : Requests)
79+
Mem->fuzzyFind(Request, [](const Symbol &S) {});
80+
}
81+
BENCHMARK(MemQueries);
82+
83+
static void DexQueries(benchmark::State &State) {
84+
const auto Dex = buildDex();
85+
const auto Requests = extractQueriesFromLogs();
86+
for (auto _ : State)
87+
for (const auto &Request : Requests)
88+
Dex->fuzzyFind(Request, [](const Symbol &S) {});
89+
}
90+
BENCHMARK(DexQueries);
91+
92+
} // namespace
93+
} // namespace clangd
94+
} // namespace clang
95+
96+
// FIXME(kbobyrev): Add index building time benchmarks.
97+
// FIXME(kbobyrev): Add memory consumption "benchmarks" by manually measuring
98+
// in-memory index size and reporting it as time.
99+
// FIXME(kbobyrev): Create a logger wrapper to suppress debugging info printer.
100+
int main(int argc, char *argv[]) {
101+
if (argc < 3) {
102+
llvm::errs() << "Usage: " << argv[0]
103+
<< " global-symbol-index.yaml fuzzy-find-requests.log "
104+
"BENCHMARK_OPTIONS...\n";
105+
return -1;
106+
}
107+
IndexFilename = argv[1];
108+
LogFilename = argv[2];
109+
// Trim first two arguments of the benchmark invocation.
110+
argv += 3;
111+
argc -= 3;
112+
::benchmark::Initialize(&argc, argv);
113+
::benchmark::RunSpecifiedBenchmarks();
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace clang {
2+
namespace clangd {
3+
namespace dex {
4+
class Dex;
5+
} // namespace dex
6+
} // namespace clangd
7+
} // namespace clang
8+
9+
namespace llvm {
10+
namespace sys {
11+
12+
int getHostNumPhysicalCores();
13+
14+
} // namespace sys
15+
} // namespace llvm
16+
17+
namespace {
18+
int Variable;
19+
} // namespace
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "BenchmarkHeader.h"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
V[09:08:34.301] Code complete: fuzzyFind("s", scopes=[llvm::])
2+
V[09:08:34.368] Code complete: fuzzyFind("sy", scopes=[llvm::])
3+
V[09:08:34.442] Code complete: fuzzyFind("sys", scopes=[llvm::])
4+
V[09:09:12.075] Code complete: fuzzyFind("Dex", scopes=[clang::clangd::, clang::, clang::clangd::dex::])
5+
V[09:09:12.075] Code complete: fuzzyFind("Variable", scopes=[])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# RUN: global-symbol-builder %p/Inputs/BenchmarkSource.cpp -- -I%p/Inputs > %t.index
2+
# RUN: %clangd-benchmark-dir/IndexBenchmark %t.index %p/Inputs/requests.log --benchmark_min_time=0.01

‎clang-tools-extra/test/lit.cfg

+6
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,9 @@ if config.clang_staticanalyzer:
137137
else:
138138
# exclude the clang-tidy test directory
139139
config.excludes.append('clang-tidy')
140+
141+
clangd_benchmarks_dir = os.path.join(os.path.dirname(config.clang_tools_dir),
142+
"tools", "clang", "tools", "extra",
143+
"clangd", "benchmarks")
144+
config.substitutions.append(('%clangd-benchmark-dir',
145+
'%s' % (clangd_benchmarks_dir)))

0 commit comments

Comments
 (0)
Please sign in to comment.