130 lines
3.5 KiB
Dart
130 lines
3.5 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
/// Service de monitoring des performances de l'application
|
|
/// Permet de mesurer les temps de chargement et d'identifier les goulots d'étranglement
|
|
class PerformanceMonitor {
|
|
static final Map<String, DateTime> _timings = {};
|
|
static final Map<String, Duration> _results = {};
|
|
static bool _enabled = kDebugMode; // Actif uniquement en mode debug par défaut
|
|
|
|
/// Active ou désactive le monitoring
|
|
static void setEnabled(bool enabled) {
|
|
_enabled = enabled;
|
|
}
|
|
|
|
/// Démarre le chronomètre pour une opération
|
|
static void start(String key) {
|
|
if (!_enabled) return;
|
|
_timings[key] = DateTime.now();
|
|
if (kDebugMode) {
|
|
print('[PerformanceMonitor] START: $key');
|
|
}
|
|
}
|
|
|
|
/// Arrête le chronomètre et affiche le résultat
|
|
static void end(String key) {
|
|
if (!_enabled) return;
|
|
|
|
if (_timings.containsKey(key)) {
|
|
final duration = DateTime.now().difference(_timings[key]!);
|
|
_results[key] = duration;
|
|
_timings.remove(key);
|
|
|
|
if (kDebugMode) {
|
|
final color = _getColorForDuration(duration);
|
|
print('[PerformanceMonitor] $color END: $key - ${duration.inMilliseconds}ms');
|
|
}
|
|
} else {
|
|
if (kDebugMode) {
|
|
print('[PerformanceMonitor] ⚠️ No start time found for: $key');
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Marque un point dans le temps (pour mesurer des étapes)
|
|
static void mark(String key) {
|
|
if (!_enabled) return;
|
|
|
|
if (kDebugMode) {
|
|
print('[PerformanceMonitor] 📍 MARK: $key');
|
|
}
|
|
}
|
|
|
|
/// Récupère les résultats de toutes les mesures
|
|
static Map<String, Duration> getResults() {
|
|
return Map.unmodifiable(_results);
|
|
}
|
|
|
|
/// Affiche un résumé des performances
|
|
static void printSummary() {
|
|
if (!_enabled || _results.isEmpty) return;
|
|
|
|
print('\n${'=' * 60}');
|
|
print('PERFORMANCE SUMMARY');
|
|
print('=' * 60);
|
|
|
|
// Trier par durée décroissante
|
|
final sortedResults = _results.entries.toList()
|
|
..sort((a, b) => b.value.compareTo(a.value));
|
|
|
|
for (var entry in sortedResults) {
|
|
final color = _getColorForDuration(entry.value);
|
|
final ms = entry.value.inMilliseconds;
|
|
print('$color ${entry.key.padRight(40)} : ${ms.toString().padLeft(6)}ms');
|
|
}
|
|
|
|
final total = _results.values.fold<Duration>(
|
|
Duration.zero,
|
|
(sum, duration) => sum + duration,
|
|
);
|
|
print('=' * 60);
|
|
print('TOTAL: ${total.inMilliseconds}ms');
|
|
print('=' * 60 + '\n');
|
|
}
|
|
|
|
/// Réinitialise toutes les mesures
|
|
static void reset() {
|
|
_timings.clear();
|
|
_results.clear();
|
|
if (kDebugMode) {
|
|
print('[PerformanceMonitor] 🔄 Reset');
|
|
}
|
|
}
|
|
|
|
/// Retourne une couleur basée sur la durée (pour les logs)
|
|
static String _getColorForDuration(Duration duration) {
|
|
final ms = duration.inMilliseconds;
|
|
if (ms < 100) return '🟢'; // Rapide
|
|
if (ms < 500) return '🟡'; // Moyen
|
|
if (ms < 1000) return '🟠'; // Lent
|
|
return '🔴'; // Très lent
|
|
}
|
|
|
|
/// Mesure une opération asynchrone
|
|
static Future<T> measure<T>(String key, Future<T> Function() operation) async {
|
|
start(key);
|
|
try {
|
|
final result = await operation();
|
|
end(key);
|
|
return result;
|
|
} catch (e) {
|
|
end(key);
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
/// Mesure une opération synchrone
|
|
static T measureSync<T>(String key, T Function() operation) {
|
|
start(key);
|
|
try {
|
|
final result = operation();
|
|
end(key);
|
|
return result;
|
|
} catch (e) {
|
|
end(key);
|
|
rethrow;
|
|
}
|
|
}
|
|
}
|
|
|