From 94e35769783771aa3a6868452624d6569167ff39 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 15 Jun 2025 20:30:43 -0500 Subject: [PATCH] tests, address review comments --- benchmark_extended.cpp | 161 ----------------------------------------- 1 file changed, 161 deletions(-) delete mode 100644 benchmark_extended.cpp diff --git a/benchmark_extended.cpp b/benchmark_extended.cpp deleted file mode 100644 index 261fb1246e..0000000000 --- a/benchmark_extended.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include -#include -#include -#include - -class Component { - public: - Component(int id) : id_(id) {} - - void call() { - // Minimal work to highlight iteration overhead - volatile int x = id_; - x++; - } - - bool should_skip_loop() const { return skip_; } - void set_skip(bool skip) { skip_ = skip; } - - private: - int id_; - bool skip_ = false; - char padding_[119]; // Total size ~128 bytes -}; - -int main() { - const int num_components = 40; - const int iterations = 1000000; // 1 million iterations - - std::cout << "=== Extended Performance Test ===" << std::endl; - std::cout << "Components: " << num_components << std::endl; - std::cout << "Iterations: " << iterations << std::endl; - std::cout << "Testing overhead of flag checking vs list iteration\n" << std::endl; - - // Create components - std::vector> owned; - std::vector components; - for (int i = 0; i < num_components; i++) { - owned.push_back(std::make_unique(i)); - components.push_back(owned.back().get()); - } - - // Test 1: All components active (best case for both) - { - std::cout << "--- Test 1: All components active ---" << std::endl; - - // Vector test - auto start = std::chrono::high_resolution_clock::now(); - for (int iter = 0; iter < iterations; iter++) { - for (auto *comp : components) { - if (!comp->should_skip_loop()) { - comp->call(); - } - } - } - auto end = std::chrono::high_resolution_clock::now(); - auto vector_duration = std::chrono::duration_cast(end - start); - - // List test - std::list list_components(components.begin(), components.end()); - start = std::chrono::high_resolution_clock::now(); - for (int iter = 0; iter < iterations; iter++) { - for (auto *comp : list_components) { - comp->call(); - } - } - end = std::chrono::high_resolution_clock::now(); - auto list_duration = std::chrono::duration_cast(end - start); - - std::cout << "Vector: " << vector_duration.count() << " µs" << std::endl; - std::cout << "List: " << list_duration.count() << " µs" << std::endl; - std::cout << "List is " << std::fixed << std::setprecision(1) - << (list_duration.count() * 100.0 / vector_duration.count() - 100) << "% slower\n" - << std::endl; - } - - // Test 2: 25% components disabled (ESPHome scenario) - { - std::cout << "--- Test 2: 25% components disabled ---" << std::endl; - - // Disable 25% of components - for (int i = 0; i < num_components / 4; i++) { - components[i]->set_skip(true); - } - - // Vector test - auto start = std::chrono::high_resolution_clock::now(); - long long checks = 0, calls = 0; - for (int iter = 0; iter < iterations; iter++) { - for (auto *comp : components) { - checks++; - if (!comp->should_skip_loop()) { - calls++; - comp->call(); - } - } - } - auto end = std::chrono::high_resolution_clock::now(); - auto vector_duration = std::chrono::duration_cast(end - start); - - // List test (with only active components) - std::list list_components; - for (auto *comp : components) { - if (!comp->should_skip_loop()) { - list_components.push_back(comp); - } - } - - start = std::chrono::high_resolution_clock::now(); - long long list_calls = 0; - for (int iter = 0; iter < iterations; iter++) { - for (auto *comp : list_components) { - list_calls++; - comp->call(); - } - } - end = std::chrono::high_resolution_clock::now(); - auto list_duration = std::chrono::duration_cast(end - start); - - std::cout << "Vector: " << vector_duration.count() << " µs (" << checks << " checks, " << calls << " calls)" - << std::endl; - std::cout << "List: " << list_duration.count() << " µs (" << list_calls << " calls, no wasted checks)" << std::endl; - std::cout << "Wasted work in vector: " << (checks - calls) << " flag checks" << std::endl; - - double overhead_percent = (vector_duration.count() - list_duration.count()) * 100.0 / list_duration.count(); - if (overhead_percent > 0) { - std::cout << "Vector is " << std::fixed << std::setprecision(1) << overhead_percent - << "% slower due to flag checking\n" - << std::endl; - } else { - std::cout << "List is " << std::fixed << std::setprecision(1) << -overhead_percent << "% slower\n" << std::endl; - } - } - - // Test 3: Measure just the flag check overhead - { - std::cout << "--- Test 3: Pure flag check overhead ---" << std::endl; - - // Just flag checks, no calls - auto start = std::chrono::high_resolution_clock::now(); - long long skipped = 0; - for (int iter = 0; iter < iterations; iter++) { - for (auto *comp : components) { - if (comp->should_skip_loop()) { - skipped++; - } - } - } - auto end = std::chrono::high_resolution_clock::now(); - auto check_duration = std::chrono::duration_cast(end - start); - - std::cout << "Time for " << (iterations * num_components) << " flag checks: " << check_duration.count() << " µs" - << std::endl; - std::cout << "Average per flag check: " << (check_duration.count() * 1000.0 / (iterations * num_components)) - << " ns" << std::endl; - std::cout << "Checks that would skip work: " << skipped << std::endl; - } - - return 0; -} \ No newline at end of file