* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <benchmark/benchmark.h>
#include <memory>
#include <numeric>
#include <string>
#include <unordered_map>
#include <vector>
* @brief Provides baseline performance measurements for UI operations.
* The ratio between baseline and actual code performance can be tracked to prevent regressions.
*/
struct MockUINode {
int32_t id;
std::string tag;
float x, y, width, height;
std::vector<std::shared_ptr<MockUINode>> children;
std::unordered_map<std::string, float> properties;
MockUINode(int32_t nodeId, const std::string& nodeTag) : id(nodeId), tag(nodeTag), x(0), y(0), width(0), height(0)
{}
};
static void BaselineNodeCreation(benchmark::State& state)
{
const int nodeCount = 10;
for (auto _ : state) {
std::vector<std::shared_ptr<MockUINode>> nodes;
nodes.reserve(nodeCount);
for (int i = 0; i < nodeCount; ++i) {
auto node = std::make_shared<MockUINode>(i, "Node" + std::to_string(i));
node->properties["opacity"] = 1.0f;
node->properties["rotation"] = 0.0f;
nodes.push_back(node);
}
benchmark::DoNotOptimize(nodes);
}
}
static void BaselineTreeConstruction(benchmark::State& state)
{
const int childCount = 10;
for (auto _ : state) {
auto root = std::make_shared<MockUINode>(0, "Root");
for (int i = 1; i <= childCount; ++i) {
auto child = std::make_shared<MockUINode>(i, "Child" + std::to_string(i));
root->children.push_back(child);
}
benchmark::DoNotOptimize(root);
}
}
static void BaselineLayoutCalculation(benchmark::State& state)
{
const int nodeCount = 10;
std::vector<std::shared_ptr<MockUINode>> nodes;
for (int i = 0; i < nodeCount; ++i) {
auto node = std::make_shared<MockUINode>(i, "Node" + std::to_string(i));
nodes.push_back(node);
}
for (auto _ : state) {
float totalWidth = 0;
float totalHeight = 0;
for (auto& node : nodes) {
node->width = static_cast<float>(node->id % 100 + 50);
node->height = static_cast<float>(node->id % 80 + 30);
node->x = totalWidth;
node->y = static_cast<float>(node->id / 10 * 50);
totalWidth += node->width + 5.0f;
totalHeight = std::max(totalHeight, node->y + node->height);
}
benchmark::DoNotOptimize(totalWidth);
benchmark::DoNotOptimize(totalHeight);
}
}
static void BaselinePropertyUpdate(benchmark::State& state)
{
const int nodeCount = 10;
std::vector<std::shared_ptr<MockUINode>> nodes;
for (int i = 0; i < nodeCount; ++i) {
auto node = std::make_shared<MockUINode>(i, "Node" + std::to_string(i));
node->properties["opacity"] = 1.0f;
node->properties["rotation"] = 0.0f;
node->properties["scale"] = 1.0f;
nodes.push_back(node);
}
for (auto _ : state) {
for (auto& node : nodes) {
node->properties["opacity"] = static_cast<float>(node->id % 100) / 100.0f;
node->properties["rotation"] = static_cast<float>(node->id % 360);
node->properties["scale"] = 1.0f + static_cast<float>(node->id % 50) / 100.0f;
}
benchmark::DoNotOptimize(nodes);
}
}
static void BaselineTreeTraversal(benchmark::State& state)
{
const int level1Count = 10;
const int level2Count = 10;
auto root = std::make_shared<MockUINode>(0, "Root");
int nodeId = 1;
for (int level1 = 0; level1 < level1Count; ++level1) {
auto child1 = std::make_shared<MockUINode>(nodeId++, "Level1_" + std::to_string(level1));
for (int level2 = 0; level2 < level2Count; ++level2) {
auto child2 = std::make_shared<MockUINode>(nodeId++, "Level2_" + std::to_string(level2));
child1->children.push_back(child2);
}
root->children.push_back(child1);
}
for (auto _ : state) {
int visitCount = 0;
std::function<void(const std::shared_ptr<MockUINode>&)> traverse =
[&](const std::shared_ptr<MockUINode>& node) {
visitCount++;
for (auto& child : node->children) {
traverse(child);
}
};
traverse(root);
benchmark::DoNotOptimize(visitCount);
}
}
BENCHMARK(BaselineNodeCreation);
BENCHMARK(BaselineTreeConstruction);
BENCHMARK(BaselineLayoutCalculation);
BENCHMARK(BaselinePropertyUpdate);
BENCHMARK(BaselineTreeTraversal);
BENCHMARK_MAIN();