blob: 44af02023db9cdddd462512ba1075fb3ab9e64d7 [file] [log] [blame]
Kirill Bobyrev73c201d2018-09-12 07:49:44 +00001//===--- 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
21const char *IndexFilename;
22const char *LogFilename;
23
24namespace clang {
25namespace clangd {
26namespace {
27
28std::unique_ptr<clang::clangd::SymbolIndex> buildMem() {
29 return clang::clangd::loadIndex(IndexFilename, {}, false);
30}
31
32std::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.
43std::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
74static 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}
81BENCHMARK(MemQueries);
82
83static 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}
90BENCHMARK(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.
100int 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}