#include "PerformanceLogger.h" PerformanceLogger &PerformanceLogger::instance() { static PerformanceLogger logger; return logger; } void PerformanceLogger::beginSession(const QString &sessionName) { QMutexLocker locker(&m_mutex); m_sessionName = sessionName; m_sessionActive = true; } void PerformanceLogger::endSession() { QMutexLocker locker(&m_mutex); m_sessionActive = false; } void PerformanceLogger::log(const QString &category, const QString &name, qint64 elapsedMs) { QMutexLocker locker(&m_mutex); Record rec; rec.category = category; rec.name = name; rec.elapsedMs = elapsedMs; rec.timestamp = QDateTime::currentDateTime(); m_records.append(rec); } QVector PerformanceLogger::records() const { QMutexLocker locker(&m_mutex); return m_records; } void PerformanceLogger::clear() { QMutexLocker locker(&m_mutex); m_records.clear(); } QString PerformanceLogger::reportString() const { QMutexLocker locker(&m_mutex); QString report; QTextStream ts(&report); ts << "==================================================\n"; ts << "Performance Report"; if (!m_sessionName.isEmpty()) ts << " - " << m_sessionName; ts << "\n"; ts << "Generated: " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n"; ts << "==================================================\n"; if (m_records.isEmpty()) { ts << "No records.\n"; return report; } // Group by category QString currentCategory; qint64 categoryTotal = 0; for (const auto &rec : m_records) { if (rec.category != currentCategory) { if (!currentCategory.isEmpty()) { ts << " [Category Total: " << categoryTotal << " ms]\n\n"; } currentCategory = rec.category; categoryTotal = 0; ts << "[" << currentCategory << "]\n"; } ts << " " << rec.name << ": " << rec.elapsedMs << " ms\n"; categoryTotal += rec.elapsedMs; } if (!currentCategory.isEmpty()) { ts << " [Category Total: " << categoryTotal << " ms]\n"; } ts << "\n==================================================\n"; ts << "Grand Total: "; qint64 grandTotal = 0; for (const auto &rec : m_records) grandTotal += rec.elapsedMs; ts << grandTotal << " ms\n"; ts << "==================================================\n"; return report; } void PerformanceLogger::printReport() const { const QString report = reportString(); qDebug().noquote() << report; } void PerformanceLogger::saveToFile(const QString &filePath) const { QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { qDebug() << "PerformanceLogger: failed to open" << filePath; return; } QTextStream ts(&file); ts << reportString(); file.close(); } ScopedPerfTimer::ScopedPerfTimer(const QString &category, const QString &name) : m_category(category), m_name(name) { m_timer.start(); } ScopedPerfTimer::~ScopedPerfTimer() { const qint64 elapsed = m_timer.elapsed(); PerformanceLogger::instance().log(m_category, m_name, elapsed); }