blob: b3c6b468e544435a8790ff0d3a9bc939c0f8e05e [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/storage/lib/vfs/cpp/pseudo_dir.h"
#include <zircon/syscalls.h>
#include <random>
#include <vector>
#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <perftest/perftest.h>
#include "src/lib/fxl/strings/string_printf.h"
#include "src/storage/lib/vfs/cpp/pseudo_file.h"
#include "util.h"
namespace {
// Benchmark baseline creation time.
bool PseudoDirCreateTest(perftest::RepeatState* state) {
while (state->KeepRunning()) {
perftest::DoNotOptimize(fbl::MakeRefCounted<fs::PseudoDir>());
}
return true;
}
// Benchmark the time to remove an existing entry and add it back.
// Parameterized by the number of files.
bool PseudoDirRemoveAddTest(perftest::RepeatState* state, int file_count) {
auto file_names = util::MakeDeterministicNamesList(file_count);
auto dir = fbl::MakeRefCounted<fs::PseudoDir>();
auto file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>();
for (const auto& name : file_names) {
dir->AddEntry(name, file);
}
int i = 0;
while (state->KeepRunning()) {
dir->RemoveEntry(file_names[i]);
dir->AddEntry(file_names[i], file);
i = (i + 1) % file_names.size();
}
return true;
}
// Benchmark the time to lookup an existing entry.
// Parameterized by the number of files.
bool PseudoDirLookupTest(perftest::RepeatState* state, int file_count) {
auto file_names = util::MakeDeterministicNamesList(file_count);
auto dir = fbl::MakeRefCounted<fs::PseudoDir>();
auto file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>();
for (const auto& name : file_names) {
dir->AddEntry(name, file);
}
int i = 0;
fbl::RefPtr<fs::Vnode> out;
while (state->KeepRunning()) {
dir->Lookup(file_names[i], &out);
i = (i + 1) % file_names.size();
}
return true;
}
// Benchmark the time to read out a directory.
// Parameterized by the number of files and the size of the output buffer.
bool PseudoDirReaddirTest(perftest::RepeatState* state, int file_count, int buffer_size) {
auto file_names = util::MakeDeterministicNamesList(file_count);
std::vector<char> buffer(buffer_size);
auto dir = fbl::MakeRefCounted<fs::PseudoDir>();
auto file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>();
for (const auto& name : file_names) {
dir->AddEntry(name, file);
}
fs::VdirCookie cookie;
while (state->KeepRunning()) {
size_t real_len = 0;
do {
auto status = dir->Readdir(&cookie, buffer.data(), buffer.size(), &real_len);
ZX_DEBUG_ASSERT(ZX_OK == status);
} while (real_len > 0);
}
return true;
}
void RegisterTests() {
perftest::RegisterTest("PseudoDir/Create", PseudoDirCreateTest);
for (int file_count = 1; file_count <= 1 << 14; file_count *= 8) {
auto name = fbl::StringPrintf("PseudoDir/RemoveAdd/%d", file_count);
perftest::RegisterTest(name.c_str(), PseudoDirRemoveAddTest, file_count);
}
for (int file_count = 1; file_count <= 1 << 14; file_count *= 8) {
auto name = fbl::StringPrintf("PseudoDir/Lookup/%d", file_count);
perftest::RegisterTest(name.c_str(), PseudoDirLookupTest, file_count);
}
for (int buffer_size = 1; buffer_size <= 64; buffer_size *= 8) {
for (int file_count = 1; file_count <= 1 << 14; file_count *= 8) {
auto name = fbl::StringPrintf("PseudoDir/Readdir/%d/%dk", file_count, buffer_size);
perftest::RegisterTest(name.c_str(), PseudoDirReaddirTest, file_count, buffer_size * 1024);
}
}
}
PERFTEST_CTOR(RegisterTests)
} // namespace