Index: clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp =================================================================== --- clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp +++ clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp @@ -33,6 +33,19 @@ return loadIndex(IndexFilename, {}, true); } +SymbolSlab loadSlab() { + auto IndexFile = readIndexFile(IndexFilename); + if (!IndexFile) { + llvm::errs() << llvm::toString(IndexFile.takeError()) << '\n'; + exit(1); + } else if (!IndexFile->Symbols) { + llvm::errs() << "Couldn't read symbol slab from the index file: " + << IndexFilename << '\n'; + exit(1); + } + return std::move(*IndexFile->Symbols); +} + // Reads JSON array of serialized FuzzyFindRequest's from user-provided file. std::vector extractQueriesFromLogs() { std::ifstream InputStream(RequestsFilename); @@ -73,7 +86,7 @@ for (const auto &Request : Requests) Mem->fuzzyFind(Request, [](const Symbol &S) {}); } -BENCHMARK(MemQueries); +BENCHMARK(MemQueries)->Unit(benchmark::kMillisecond); static void DexQueries(benchmark::State &State) { const auto Dex = buildDex(); @@ -82,15 +95,72 @@ for (const auto &Request : Requests) Dex->fuzzyFind(Request, [](const Symbol &S) {}); } -BENCHMARK(DexQueries); +BENCHMARK(DexQueries)->Unit(benchmark::kMillisecond); + +// This is not a *real* benchmark: it shows size of built MemIndex (in bytes). +// Same for the next "benchmark". +// FIXME(kbobyrev): Track memory usage caused by different index parts: +// SymbolSlab and RefSlabs, InverseIndex, PostingLists of different types for +// Dex, etc. +static void MemSize(benchmark::State &State) { + const auto Mem = buildMem(); + for (auto _ : State) + // Divide size of Mem by 1000 so that it will be correctly displayed in the + // benchmark report (possible options for time units are ms, ns and us). + State.SetIterationTime(/*double Seconds=*/Mem->estimateMemoryUsage() / + 1000.0); + State.SetLabel("This tracks in-memory size of MemIndex (SymbolSlab + Index " + "overhead) in bytes"); +} +BENCHMARK(MemSize) + ->UseManualTime() + ->Unit(benchmark::kMillisecond) + ->Iterations(1); + +static void DexSize(benchmark::State &State) { + const auto Dex = buildDex(); + + for (auto _ : State) + State.SetIterationTime(Dex->estimateMemoryUsage() / 1000.0); + State.SetLabel("This tracks in-memory size of Dex (SymbolSlab + Index " + "overhead) in bytes"); +} +BENCHMARK(DexSize) + ->UseManualTime() + ->Unit(benchmark::kMillisecond) + ->Iterations(1); + +static void DexOverhead(benchmark::State &State) { + const auto Slab = loadSlab(); + const auto Dex = buildDex(); + for (auto _ : State) + State.SetIterationTime((Dex->estimateMemoryUsage() - Slab.bytes()) / + 1000.0); + State.SetLabel("This tracks in-memory size of Dex Index overhead (and " + "excludes underlying SymbolSlab size) in bytes"); +} +BENCHMARK(DexOverhead) + ->UseManualTime() + ->Unit(benchmark::kMillisecond) + ->Iterations(1); + +static void SymbolSlabLoading(benchmark::State &State) { + for (auto _ : State) + benchmark::DoNotOptimize(loadSlab()); +} +BENCHMARK(SymbolSlabLoading)->Unit(benchmark::kMillisecond); + +static void DexBuild(benchmark::State &State) { + auto Slab = loadSlab(); + for (auto _ : State) + benchmark::DoNotOptimize(dex::Dex::build(std::move(Slab), {})); +} +BENCHMARK(DexBuild)->Unit(benchmark::kMillisecond); } // namespace } // namespace clangd } // namespace clang -// FIXME(kbobyrev): Add index building time benchmarks. -// FIXME(kbobyrev): Add memory consumption "benchmarks" by manually measuring -// in-memory index size and reporting it as time. // FIXME(kbobyrev): Create a logger wrapper to suppress debugging info printer. int main(int argc, char *argv[]) { if (argc < 3) {