1 //===--- IndexBenchmark.cpp - Clangd index benchmarks -----------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "../index/Serialization.h"
10 #include "../index/dex/Dex.h"
11 #include "benchmark/benchmark.h"
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/Regex.h"
18 const char *IndexFilename
;
19 const char *RequestsFilename
;
25 std::unique_ptr
<SymbolIndex
> buildMem() {
26 return loadIndex(IndexFilename
, clang::clangd::SymbolOrigin::Static
,
30 std::unique_ptr
<SymbolIndex
> buildDex() {
31 return loadIndex(IndexFilename
, clang::clangd::SymbolOrigin::Static
,
35 // Reads JSON array of serialized FuzzyFindRequest's from user-provided file.
36 std::vector
<FuzzyFindRequest
> extractQueriesFromLogs() {
38 auto Buffer
= llvm::MemoryBuffer::getFile(RequestsFilename
);
40 llvm::errs() << "Error cannot open JSON request file:" << RequestsFilename
41 << ": " << Buffer
.getError().message() << "\n";
45 StringRef Log
= Buffer
.get()->getBuffer();
47 std::vector
<FuzzyFindRequest
> Requests
;
48 auto JSONArray
= llvm::json::parse(Log
);
50 // Panic if the provided file couldn't be parsed.
52 llvm::errs() << "Error when parsing JSON requests file: "
53 << llvm::toString(JSONArray
.takeError());
56 if (!JSONArray
->getAsArray()) {
57 llvm::errs() << "Error: top-level value is not a JSON array: " << Log
62 for (const auto &Item
: *JSONArray
->getAsArray()) {
63 FuzzyFindRequest Request
;
64 // Panic if the provided file couldn't be parsed.
65 llvm::json::Path::Root
Root("FuzzyFindRequest");
66 if (!fromJSON(Item
, Request
, Root
)) {
67 llvm::errs() << llvm::toString(Root
.getError()) << "\n";
68 Root
.printErrorContext(Item
, llvm::errs());
71 Requests
.push_back(Request
);
76 static void memQueries(benchmark::State
&State
) {
77 const auto Mem
= buildMem();
78 const auto Requests
= extractQueriesFromLogs();
80 for (const auto &Request
: Requests
)
81 Mem
->fuzzyFind(Request
, [](const Symbol
&S
) {});
83 BENCHMARK(memQueries
);
85 static void dexQueries(benchmark::State
&State
) {
86 const auto Dex
= buildDex();
87 const auto Requests
= extractQueriesFromLogs();
89 for (const auto &Request
: Requests
)
90 Dex
->fuzzyFind(Request
, [](const Symbol
&S
) {});
92 BENCHMARK(dexQueries
);
94 static void dexBuild(benchmark::State
&State
) {
101 } // namespace clangd
104 // FIXME(kbobyrev): Add index building time benchmarks.
105 // FIXME(kbobyrev): Add memory consumption "benchmarks" by manually measuring
106 // in-memory index size and reporting it as time.
107 // FIXME(kbobyrev): Create a logger wrapper to suppress debugging info printer.
108 int main(int argc
, char *argv
[]) {
110 llvm::errs() << "Usage: " << argv
[0]
111 << " global-symbol-index.dex requests.json "
112 "BENCHMARK_OPTIONS...\n";
115 IndexFilename
= argv
[1];
116 RequestsFilename
= argv
[2];
117 // Trim first two arguments of the benchmark invocation and pretend no
118 // arguments were passed in the first place.
122 ::benchmark::Initialize(&argc
, argv
);
123 ::benchmark::RunSpecifiedBenchmarks();