blob: fc7ce65d5d16644e8fd22e55a365cbdb74a7b3a3 [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 <random>
#include <vector>
#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <lib/fxl/strings/string_printf.h>
#include <perftest/perftest.h>
#include <zircon/syscalls.h>
#include <iostream>
#include <sstream>
#include "lib/component/cpp/exposed_object.h"
namespace {
using ByteVector = component::Property::ByteVector;
using component::ObjectPath;
const char kValue[] = "value";
const int kSmallPropertySize = 8;
const int kLargePropertySize = 10000;
const ObjectPath kPath0 = {};
const ObjectPath kPath1 = {"a"};
const ObjectPath kPath2 = {"a", "b"};
const ObjectPath kPath10 = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
class NumericItem : public component::ExposedObject {
public:
NumericItem(ObjectPath path) : ExposedObject(UniqueName("itemN-")), path_{std::move(path)} {
object_dir().set_metric(path_, kValue, component::IntMetric(0));
}
NumericItem() : NumericItem(ObjectPath()) {}
void increment() {
object_dir().add_metric(path_, kValue, 1);
}
private:
ObjectPath path_;
};
class PropertyItem : public component::ExposedObject {
public:
PropertyItem() : ExposedObject(UniqueName("itemS-")) {
object_dir().set_prop(kValue, component::Property());
}
void set(std::string str_value) { object_dir().set_prop(kValue, std::move(str_value)); }
void set(ByteVector vector_value) { object_dir().set_prop(kValue, std::move(vector_value)); }
};
// Measure the time taken to create and destroy metrics and properties.
bool TestExposedObjectLifecycle(perftest::RepeatState* state) {
state->DeclareStep("MetricCreate");
state->DeclareStep("MetricDestroy");
state->DeclareStep("PropertyCreate");
state->DeclareStep("PropertyDestroy");
while (state->KeepRunning()) {
{
NumericItem item;
state->NextStep();
}
state->NextStep();
{
PropertyItem item;
state->NextStep();
}
}
return true;
}
// Measure the time taken to increment an IntMetric.
bool TestExposedObjectIncrement(perftest::RepeatState* state) {
NumericItem item;
while (state->KeepRunning()) {
item.increment();
}
return true;
}
// Measure the time taken to increment an IntMetric, given a path.
bool TestIncrementPath(perftest::RepeatState* state, ObjectPath path) {
NumericItem item(path);
while (state->KeepRunning()) {
item.increment();
}
return true;
}
// Measure the time taken to change a String property.
bool TestExposedObjectSetString(perftest::RepeatState* state, int size) {
PropertyItem item;
std::string string;
string.resize(size, 'a');
while (state->KeepRunning()) {
item.set(string);
}
return true;
}
// Measure the time taken to change a ByteVector property.
bool TestExposedObjectSetVector(perftest::RepeatState* state, int size) {
PropertyItem item;
ByteVector vector;
vector.resize(size, 'a');
while (state->KeepRunning()) {
item.set(vector);
}
return true;
}
bool TestExposedObjectParenting(perftest::RepeatState* state) {
NumericItem parent;
NumericItem child1;
NumericItem child2;
NumericItem child3;
state->DeclareStep("AddFirst");
state->DeclareStep("AddSecond");
state->DeclareStep("AddFirstAgain");
state->DeclareStep("AddThird");
state->DeclareStep("RemoveFirst");
state->DeclareStep("RemoveSecond");
state->DeclareStep("RemoveFirstAgain");
state->DeclareStep("RemoveThird");
while (state->KeepRunning()) {
child1.set_parent(parent.object_dir());
state->NextStep();
child2.set_parent(parent.object_dir());
state->NextStep();
child1.set_parent(parent.object_dir());
state->NextStep();
child3.set_parent(parent.object_dir());
state->NextStep();
child1.remove_from_parent();
state->NextStep();
child2.remove_from_parent();
state->NextStep();
child1.remove_from_parent();
state->NextStep();
child3.remove_from_parent();
}
return true;
}
// /pkgfs/packages/instrumentation_benchmarks/0/test/instrumentation_benchmarks -p
void RegisterTests() {
perftest::RegisterTest("Expose/ExposedObject/Lifecycle", TestExposedObjectLifecycle);
perftest::RegisterTest("Expose/ExposedObject/Increment", TestExposedObjectIncrement);
perftest::RegisterTest("Expose/ExposedObject/Parenting", TestExposedObjectParenting);
perftest::RegisterTest("Expose/ExposedObject/Path/0", TestIncrementPath, kPath0);
perftest::RegisterTest("Expose/ExposedObject/Path/1", TestIncrementPath, kPath1);
perftest::RegisterTest("Expose/ExposedObject/Path/2", TestIncrementPath, kPath2);
perftest::RegisterTest("Expose/ExposedObject/Path/10", TestIncrementPath, kPath10);
perftest::RegisterTest(fxl::StringPrintf("Expose/ExposedObject/SetString/%d",
kSmallPropertySize).c_str(),
TestExposedObjectSetString, kSmallPropertySize);
perftest::RegisterTest(fxl::StringPrintf("Expose/ExposedObject/SetString/%d",
kLargePropertySize).c_str(),
TestExposedObjectSetString, kLargePropertySize);
perftest::RegisterTest(fxl::StringPrintf("Expose/ExposedObject/SetVector/%d",
kSmallPropertySize).c_str(),
TestExposedObjectSetVector, kSmallPropertySize);
perftest::RegisterTest(fxl::StringPrintf("Expose/ExposedObject/SetVector/%d",
kLargePropertySize).c_str(),
TestExposedObjectSetVector, kLargePropertySize);
}
PERFTEST_CTOR(RegisterTests);
} // namespace