Add real-time performance profiling infrastructure to monitor frame times, render performance, and identify bottlenecks. Features: - Profiler.h: ScopedTimer RAII helper for automatic timing measurements - ProfilerOverlay: F3-togglable overlay displaying real-time metrics - Detailed timing breakdowns: grid rendering, entity rendering, FOV, Python callbacks, and animation updates - Per-frame counters: cells rendered, entities rendered, draw calls - Performance color coding: green (<16ms), yellow (<33ms), red (>33ms) - Benchmark suite: static grid and moving entities performance tests Integration: - GameEngine: Integrated profiler overlay with F3 toggle - UIGrid: Added timing instrumentation for grid and entity rendering - Metrics tracked in ProfilingMetrics struct with 60-frame averaging Usage: - Press F3 in-game to toggle profiler overlay - Run benchmarks with tests/benchmark_*.py scripts - ScopedTimer automatically measures code block execution time This addresses issue #104 (Basic profiling/metrics). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
61 lines
1.3 KiB
C++
61 lines
1.3 KiB
C++
#include "Profiler.h"
|
|
#include <iostream>
|
|
|
|
ProfilingLogger::ProfilingLogger()
|
|
: headers_written(false)
|
|
{
|
|
}
|
|
|
|
ProfilingLogger::~ProfilingLogger() {
|
|
close();
|
|
}
|
|
|
|
bool ProfilingLogger::open(const std::string& filename, const std::vector<std::string>& columns) {
|
|
column_names = columns;
|
|
file.open(filename);
|
|
|
|
if (!file.is_open()) {
|
|
std::cerr << "Failed to open profiling log file: " << filename << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Write CSV header
|
|
for (size_t i = 0; i < columns.size(); ++i) {
|
|
file << columns[i];
|
|
if (i < columns.size() - 1) {
|
|
file << ",";
|
|
}
|
|
}
|
|
file << "\n";
|
|
file.flush();
|
|
|
|
headers_written = true;
|
|
return true;
|
|
}
|
|
|
|
void ProfilingLogger::writeRow(const std::vector<float>& values) {
|
|
if (!file.is_open()) {
|
|
return;
|
|
}
|
|
|
|
if (values.size() != column_names.size()) {
|
|
std::cerr << "ProfilingLogger: value count (" << values.size()
|
|
<< ") doesn't match column count (" << column_names.size() << ")" << std::endl;
|
|
return;
|
|
}
|
|
|
|
for (size_t i = 0; i < values.size(); ++i) {
|
|
file << values[i];
|
|
if (i < values.size() - 1) {
|
|
file << ",";
|
|
}
|
|
}
|
|
file << "\n";
|
|
}
|
|
|
|
void ProfilingLogger::close() {
|
|
if (file.is_open()) {
|
|
file.flush();
|
|
file.close();
|
|
}
|
|
}
|