mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
f13513239d
- Use CodSpeed's codspeed-cpp fork with proper instrumentation for simulation mode benchmark detection - setup_codspeed_lib.py creates a flat PlatformIO-compatible library by combining google_benchmark sources, codspeed core, and instrument-hooks into a single library directory - Renames .cc to .cpp (PlatformIO doesn't compile .cc by default) - Adds all required defines: CODSPEED_ENABLED, CODSPEED_SIMULATION, CODSPEED_VERSION, CODSPEED_ROOT_DIR, CODSPEED_MODE_DISPLAY - Output JSON config consumed by cpp_benchmark.py via env var
107 lines
3.4 KiB
Python
Executable File
107 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Build and run C++ benchmarks for ESPHome components using Google Benchmark."""
|
|
|
|
import argparse
|
|
import os
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
from helpers import root_path
|
|
from test_helpers import PLATFORMIO_GOOGLE_BENCHMARK_LIB, build_and_run
|
|
|
|
# Path to /tests/benchmarks/components
|
|
BENCHMARKS_DIR: Path = Path(root_path) / "tests" / "benchmarks" / "components"
|
|
|
|
# Path to /tests/benchmarks/core (always included, not a component)
|
|
CORE_BENCHMARKS_DIR: Path = Path(root_path) / "tests" / "benchmarks" / "core"
|
|
|
|
# Components whose to_code should run during benchmark builds.
|
|
# core/host/logger are infrastructure. json is needed because its
|
|
# to_code adds the ArduinoJson library (it's auto-loaded by api but
|
|
# cpp_testing suppresses to_code for components not in this set).
|
|
BENCHMARK_CODEGEN_COMPONENTS = {"core", "host", "logger", "json"}
|
|
|
|
PLATFORMIO_OPTIONS = {
|
|
"build_flags": [
|
|
"-DUSE_TIME_TIMEZONE", # enable timezone code paths
|
|
"-g", # debug symbols for profiling
|
|
],
|
|
# Use deep+ LDF mode to ensure PlatformIO detects the benchmark
|
|
# library dependency from nested includes.
|
|
"lib_ldf_mode": "deep+",
|
|
}
|
|
|
|
|
|
def run_benchmarks(selected_components: list[str], build_only: bool = False) -> int:
|
|
# Allow CI to override the benchmark library (e.g. with CodSpeed's fork).
|
|
# BENCHMARK_LIB_CONFIG is a JSON string from setup_codspeed_lib.py
|
|
# containing {"lib_path": "/path/to/google_benchmark"}.
|
|
lib_config_json = os.environ.get("BENCHMARK_LIB_CONFIG")
|
|
|
|
if lib_config_json:
|
|
import json
|
|
|
|
lib_config = json.loads(lib_config_json)
|
|
benchmark_lib = f"benchmark=symlink://{lib_config['lib_path']}"
|
|
else:
|
|
benchmark_lib = PLATFORMIO_GOOGLE_BENCHMARK_LIB
|
|
|
|
return build_and_run(
|
|
selected_components=selected_components,
|
|
tests_dir=BENCHMARKS_DIR,
|
|
codegen_components=BENCHMARK_CODEGEN_COMPONENTS,
|
|
config_prefix="cppbench",
|
|
friendly_name="CPP Benchmarks",
|
|
libraries=benchmark_lib,
|
|
platformio_options=PLATFORMIO_OPTIONS,
|
|
main_entry="main.cpp",
|
|
label="benchmarks",
|
|
build_only=build_only,
|
|
extra_include_dirs=[CORE_BENCHMARKS_DIR],
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="Build and run C++ benchmarks for ESPHome components."
|
|
)
|
|
parser.add_argument(
|
|
"components",
|
|
nargs="*",
|
|
help="List of components to benchmark (must have files in tests/benchmarks/components/).",
|
|
)
|
|
parser.add_argument(
|
|
"--all",
|
|
action="store_true",
|
|
help="Benchmark all components with benchmark files.",
|
|
)
|
|
parser.add_argument(
|
|
"--build-only",
|
|
action="store_true",
|
|
help="Only build, print binary path without running.",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.all:
|
|
# Find all component directories that have .cpp files
|
|
components: list[str] = (
|
|
sorted(
|
|
d.name
|
|
for d in BENCHMARKS_DIR.iterdir()
|
|
if d.is_dir()
|
|
and d.name != "__pycache__"
|
|
and (any(d.glob("*.cpp")) or any(d.glob("*.h")))
|
|
)
|
|
if BENCHMARKS_DIR.is_dir()
|
|
else []
|
|
)
|
|
else:
|
|
components: list[str] = args.components
|
|
|
|
sys.exit(run_benchmarks(components, build_only=args.build_only))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|