Communitygithub.com

kmgcc/macOS-Trace

Compétence Agent : optimisation fermée des performances pour applications macOS — profilage xctrace sans tête, corrections de code ciblées, re-test A/B différentiel. Fonctionne avec Claude Code, Codex, Cursor, Antigravity et plus.

Qu'est-ce que macOS-Trace ?

macOS-Trace est un moteur d'optimisation de performances autonome en boucle fermée conçu pour les applications macOS natives (SwiftUI, AppKit, Metal, CoreAudio, WebKit et binaires natifs). Son objectif principal est d'éliminer l'interaction manuelle avec l'interface graphique d'Instruments en permettant à un agent IA, comme Claude Code, Codex ou Cursor, de diagnostiquer de manière autonome les goulots d'étranglement, d'appliquer des correctifs de code ciblés et de re-tester avec des benchmarks différentiels A/B. Le processus est guidé par un protocole en quatre phases : alignement des objectifs avec l'utilisateur via un questionnaire, profilage diagnostique pour attribuer les goulots d'étranglement à l'aide de modèles Instruments spécialisés, modifications de code chirurgicales et re-test quantitatif avec une porte de décision claire. La compétence applique des règles strictes pour les agents, notamment l'établissement de lignes de base, la garantie des conditions de test équitables, l'absence de dépendances Python tierces et le nettoyage des artefacts d'enregistrement. Grâce à son approche automatisée, macOS-Trace est extrêmement utile pour les développeurs cherchant à réduire la consommation CPU/mémoire, les à-coups de l'interface utilisateur ou les temps de lancement sans manipulation manuelle des outils de profilage.

Compatible avec✓Claude Code✓Codex CLI✓Cursor✓Antigravity
npx skills add kmgcc/macOS-Trace

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

macOS-Trace : Optimisation Autonome des Performances d'Applications

macOS-Trace est un moteur d'optimisation de performances en boucle fermée pour les applications macOS natives (SwiftUI, AppKit, Metal, CoreAudio, WebKit et binaires natifs).

L'objectif est d'éliminer l'interaction manuelle avec l'interface graphique d'Instruments. Un agent IA peut diagnostiquer de manière autonome, localiser les goulots d'étranglement, implémenter des modifications de code, re-tester avec des benchmarks différentiels et itérer jusqu'à ce que les cibles de performances soient vérifiées avec des données empiriques.

+-------------------------------------------------------------------------+
|                La Boucle d'Optimisation Autonome                        |
|                                                                         |
|  1. Alignement des Objectifs ──> 2. Trace Diagnostique ──> 3. Correction de Code Ciblée |
|         ^                                                 │             |
|         │                                                 ▼             |
|         └────── Itérer si la Cible n'est pas Atteinte <── 4. Vérification par Re-Test |
+-------------------------------------------------------------------------+

Phase 1 : Alignement des Objectifs Utilisateur (Questionnaire Pré-Vol)

Avant de modifier du code ou de collecter des traces, l'agent doit s'aligner avec l'utilisateur sur les cibles d'optimisation et les critères de succès.

Outil Modal vs Interaction en Chat

  • Si votre plateforme agent fournit un outil/questionnaire interactif modal (par ex., ask_question, boîtes de dialogue de saisie ou listes d'options sélectionnables), invoquez-le pour présenter ces choix proprement à l'utilisateur.
  • Si aucun outil modal n'est disponible, demandez directement à l'utilisateur dans la conversation avec des options structurées et des valeurs recommandées concrètes.

Questions à Poser à l'Utilisateur

  1. Objectif d'Optimisation Principal :
    • Option A : Réduire l'utilisation du CPU, la consommation d'énergie et le throttling thermique.
    • Option B : Diminuer l'empreinte mémoire, les pics d'allocation transitoires ou éliminer les fuites.
    • Option C : Éliminer les saccades de trames de l'interface utilisateur et les images d'animation perdues (Hitches).
    • Option D : Accélérer le temps de lancement à froid de l'application.
  2. Cibles de Performances Spécifiques (Fournir les Valeurs Par Défaut Recommandées) :
    • Cibles CPU / Énergie :
      • Cible de Base au Repos : < 20 M/s instructions, Impact CPU < 0,5.
      • Cible de Charge de Travail Active : < 100 M/s instructions (ou spécifier : réduire de 30% à 50%).
    • Cibles Mémoire :
      • RAM Résidente Maximale : Limiter à < 150 Mo (utilitaires/audio) ou < 300 Mo (média/interface riche).
      • Taux d'Événements d'Allocation : < 500 événements/s en régime permanent.
      • Fuites Mémoire : Exactement 0 fuite persistante.
    • Cibles de Fluidité de l'Interface :
      • Ratio de Saccades : < 5,0 ms/s (acceptable), < 1,0 ms/s (fluide/aucune image perdue).
    • Cibles de Temps de Lancement :
      • Temps jusqu'à la Première Trame : < 400 ms (excellent), < 800 ms (acceptable).
  3. Scénario de Benchmark Utilisateur :
    • Demandez à l'utilisateur quel écran, interaction utilisateur ou charge de travail spécifique il souhaite benchmarker.

Une fois les cibles confirmées, passez à la Phase 2.


Périmètre et Prérequis

  • Plateforme cible : Applications de bureau macOS natives uniquement (SwiftUI, AppKit, Metal, CoreAudio / AVAudioEngine, vues hôtes WebKit, exécutables CLI natifs). Ne prend pas en charge les simulateurs iOS, les appareils mobiles distants ou les applications web externes uniquement basées sur un navigateur.
  • Outillage Xcode : Nécessite macOS 12+ et Xcode complet ou les outils en ligne de commande Xcode (xcode-select -p, xcrun xctrace version).
  • Python : Python 3.8+ (pré-installé sur macOS ; zéro dépendance pip externe).
  • Permissions de processus : Les builds de débogage ou les binaires avec l'entitlement get-task-allow sont requis pour --attach <PID> sous Runtime Renforcé.

Règles pour les Agents

Suivez ces règles non négociables lors du profilage automatisé :

  1. Établir d'abord une ligne de base : N'enregistrez jamais uniquement la charge de travail active. Capturez toujours une ligne de base au repos (application ouverte au premier plan, charge de travail en pause) avant d'enregistrer l'état actif. Calculez : Delta = Actif - Base.
  2. Vérifier l'état cible avant l'enregistrement : Assurez-vous que le processus existe en utilisant pgrep -x <NomProcessus> et que la fonctionnalité cible est activement en cours d'exécution pendant la fenêtre d'enregistrement.
  3. Garder la fenêtre au premier plan : macOS limite le rendu et les liaisons d'affichage pour les fenêtres masquées ou minimisées (NSWindowOcclusionState). Une fenêtre masquée produira des relevés CPU et GPU faussement bas.
  4. Utiliser des paramètres de test égaux : Comparez les exécutions avec des durées d'échantillonnage identiques (par défaut : 60s), des échelles d'affichage identiques, des tailles de fenêtre identiques et des données d'entrée de test identiques. Ne comparez jamais une build Debug à une build Release.
  5. Pas de dépendances Python tierces : Tous les scripts fournis (scripts/compare_elements.py, scripts/parse_power.py, scripts/top_categories.py) utilisent uniquement la bibliothèque standard Python 3. N'installez pas de paquets pip.
  6. Sauvegarder les sorties dans /tmp/macos-traces/ : Stockez tous les bundles .trace et les exportations .xml dans /tmp/macos-traces/ avec des noms de fichiers horodatés et étiquetés par scénario.
  7. Protéger le budget de contexte de conversation : Les fichiers de trace et les documents XML bruts exportés peuvent peser des dizaines ou des centaines de mégaoctets. Ne déversez jamais les sorties .trace brutes, les arbres d'appels complets ou le XML d'Allocations non analysé dans le contexte de conversation de l'agent. Utilisez toujours les scripts Python fournis pour diffuser, filtrer, classer et résumer les données avant de les lire.
  8. Se concentrer sur les goulots d'étranglement principaux : Ne dispersez pas les micro-optimisations sur des dizaines de fonctions utilitaires innocentes. Profilez d'abord pour confirmer le contributeur dominant (par exemple, instances de surface redondantes, réévaluations de temporisateurs à haute fréquence, E/S non mises en mémoire tampon) et concentrez les efforts d'optimisation exclusivement sur cette cause racine.
  9. Ne jamais modifier silencieusement l'interface utilisateur, les effets visuels ou le comportement principal : Si un goulot d'étranglement de performance implique la fidélité visuelle (comme les matériaux de flou/verre, les animations d'images, les ombres, les transitions de disposition) ou un comportement logiciel essentiel :
    • Ne supprimez pas ou ne dégradez pas unilatéralement la fonctionnalité visuelle.
    • Demandez formellement l'autorisation à l'utilisateur d'abord (en utilisant une invite interactive ou un message de chat explicite).
    • Articulez clairement le compromis : Décrivez le changement visuel avant et après, expliquez pourquoi la fonctionnalité consomme des ressources et présentez le gain de performance concret attendu (par exemple, « La désactivation du flou d'arrière-plan dynamique réduira l'impact GPU actif de 1,5 à 0,2 et économisera environ 50 M/s d'instructions CPU »).
  10. Nettoyer les artefacts d'enregistrement : Chaque enregistrement xctrace écrit plusieurs Go de traces de noyau transitoires (instruments*.ktrace) et un cache CLI d'Instruments (C/com.apple.dt.InstrumentsCLI) dans le dossier temporaire système par utilisateur ($TMPDIR). scripts/run_trace.sh les supprime automatiquement à la sortie (en cas de succès comme d'échec). Lorsque vous exécutez xctrace directement, nettoyez-les vous-même avant de conclure :
    find "${TMPDIR:-/tmp}" -maxdepth 1 -type f -name 'instruments*.ktrace' -delete 2>/dev/null || true
    
    Ne terminez jamais une session en laissant des centaines de Go de données d'enregistrement transitoires derrière vous.

Le Protocole d'Optimisation en 4 Phases

Phase 2 : Profilage Diagnostique et Attribution

Avant d'écrire du code, mesurez l'état actuel et isolez la cause racine :

# 1. Vérification pré-vol : l'application doit être en cours d'exécution avec sa fenêtre visible
APP_NAME="VotreApp"
pgrep -x "$APP_NAME" || { echo "[ERREUR] $APP_NAME n'est pas en cours d'exécution. Lancez-la d'abord."; exit 1; }

# SKILL_DIR = le répertoire d'installation de cette compétence (ajustez si installée ailleurs)
SKILL_DIR="$HOME/.claude/skills/macos-trace"

# 2. Enregistrer 60s de ligne de base au repos (charge de travail en pause, fenêtre visible)
# run_trace.sh résout lui-même le nom du processus en un PID
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "01-baseline"

# 3. Déclencher la charge de travail dans l'application, enregistrer l'état actif
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "02-pre-opt"

# 4. Calculer le delta pré-optimisation
python3 "$SKILL_DIR/scripts/compare_elements.py" \
  /tmp/macos-traces/01-baseline-power.xml:"Idle Baseline" \
  /tmp/macos-traces/02-pre-opt-power.xml:"Active Pre-Opt"

Utilisez les modèles spécialisés pour attribuer le goulot d'étranglement :

  • Exécutez --template time pour isoler les fonctions chaudes de l'arbre d'appels.
  • Exécutez --template alloc avec scripts/top_categories.py pour identifier les allocations incontrôlées.
  • Exécutez --template hitches pendant le défilement pour isoler les retards de rendu par rapport aux retards de commit.

Phase 3 : Modification de Code Ciblée

Appliquez des corrections minimales et chirurgicales basées sur les résultats :

  • Threads audio en temps réel allouant de la mémoire tas ? Remplacez par des tampons en anneau sans verrou pré-alloués.
  • IPC WebKit saturé ? Limitez les mises à jour d'état et passez aux animations CSS transform.
  • Fragment shader Metal surdessinant sur Retina ? Ajoutez un changement d'échelle de résolution dynamique ou mettez en pause les boucles de rendu hors écran.
  • Pics de décodage d'images haute résolution ? Adoptez le sous-échantillonnage CGImageSourceCreateThumbnailAtIndex.

Reconstruisez l'application.

Phase 4 : Re-Test, Revue Quantitative et Porte de Décision

Relancez le profil dans des conditions identiques et évaluez le delta :

# 1. Enregistrer la charge de travail active post-optimisation
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "03-post-opt"

# 2. Comparer Pré-Opt vs Post-Opt par rapport à la Ligne de Base
python3 "$SKILL_DIR/scripts/compare_elements.py" \
  /tmp/macos-traces/01-baseline-power.xml:"Idle Baseline" \
  /tmp/macos-traces/02-pre-opt-power.xml:"Active Pre-Opt" \
  /tmp/macos-traces/03-post-opt-power.xml:"Active Post-Opt"

Exemple de Sortie de Décision :

Scénario                Sec  CPU Avg  CPU Max  Affichage GPU Avg  Instr Total    Instr M/s
============================================================================================
Idle Baseline            60     0.15     0.80     0.05     0.00        1.02G         17.0
Active Pre-Opt           60     2.40     4.80     1.10     1.50       16.20G        270.0
Active Post-Opt          60     0.65     1.20     0.25     0.10        4.80G         80.0
--------------------------------------------------------------------------------------------
Delta vs Ligne de Base [Idle Baseline] :
  Active Pre-Opt           +253.0 M/s d'instructions, Delta CPU Moyen +2.25
  Active Post-Opt          +63.0 M/s d'instructions, Delta CPU Moyen +0.50

Porte de Décision :

  • Si la cible est atteinte (par exemple, le taux d'instructions est passé de 270 M/s à 80 M/s, satisfaisant l'objectif < 100 M/s) : Présentez le rapport avant/après empirique à l'utilisateur et concluez.
  • Si la cible n'est pas atteinte : Isolez le goulot d'étranglement restant et commencez le cycle d'itération suivant.

Nettoyage Post-Rapport : Après que l'utilisateur a accepté le rapport d'optimisation final, supprimez les bundles .trace accumulés sous /tmp/macos-traces/ (chacun peut faire des dizaines de Go) sauf si l'utilisateur demande explicitement de les conserver. Le tableau de comparaison finalisé et les exportations .xml montrés dans le rapport sont une preuve suffisante.


Référence CLI Directe

# Attacher à un processus en cours d'exécution
xcrun xctrace record \
  --template 'Power Profiler' \
  --time-limit 60s \
  --output /tmp/macos-traces/power.trace \
  --attach $PID

# Exporter la table d'Impact d'Alimentation (instructions, CPU, GPU, affichage)
xcrun xctrace export \
  --input /tmp/macos-traces/power.trace \
  --xpath "/trace-toc/run[@number='1']/data/table[@schema='ProcessSubsystemPowerImpact']" \
  > /tmp/macos-traces/power.xml

# Exporter la table récapitulative des Allocations
xcrun xctrace export \
  --input /tmp/macos-traces/alloc.trace \
  --xpath "/trace-toc/run[@number='1']/data/table[@schema='all-allocations-summary']" \
  > /tmp/macos-traces/alloc.xml

Référence des Modèles

Modèles Instruments pris en charge par scripts/run_trace.sh et xctrace sans tête :

Calcul et Énergie

ModèleNom CourtMétriques Cibles & Schéma d'ExportationCas d'Utilisation
Power ProfilerpowerInstructions/s (M/s), impacts énergétiques CPU/GPU/Affichage (ProcessSubsystemPowerImpact).Benchmarking A/B objectif et tests d'efficacité énergétique.
Time ProfilertimePoids des échantillons CPU par thread, points chauds de l'arbre d'appels, méthodes bloquantes du thread principal.Utilisation CPU élevée, threads incontrôlés et chemins de fonctions chaudes.
CPU CounterscountersIPC (instructions par cycle), échecs de cache L1/L2, prédictions de branchement erronées.Goulots d'étranglement de performance de calcul et d'algorithmes DSP de bas niveau.

Réactivité et Fluidité de l'Interface Utilisateur

ModèleNom CourtMétriques Cibles & Schéma d'ExportationCas d'Utilisation
Animation HitcheshitchesDurée des saccades (ms), ratio de saccades (ms/s), images perdues, latence de phase application vs rendu.Saccades de défilement, images d'animation perdues et retards de commit CoreAnimation.
SwiftUIswiftuiÉvaluations du corps de la vue, comptes d'invalidation d'État, fréquence de mise à jour de la vue.Réévaluations de vue inutiles et cascades d'invalidation d'État.
Metal System TracemetalTemps de l'encodeur GPU, durées des shaders de vertex/fragment, latence de limite de trame.Goulots d'étranglement d'exécution du shader, surcharge des effets de particules et blocages du pipeline de rendu.

Mémoire et Allocations

ModèleNom CourtMétriques Cibles & Schéma d'ExportationCas d'Utilisation
AllocationsallocAllocations tas, mémoire transitoire vs persistante, taux d'événements par catégorie (all-allocations-summary).Allocations temporaires à haute fréquence, pics de mémoire et gaspillage de tampons.
LeaksleaksFuites mémoire retenues qui survivent au cycle de vie parent, cycles de référence.Mémoire abandonnée, fuites de capture de fermeture et cycles de délégué non libérés.

Démarrage et Concurrence

ModèleNom CourtMétriques Cibles & Schéma d'ExportationCas d'Utilisation
App LaunchlaunchTemps jusqu'à la première trame, temps de chargement dyld, initialiseurs statiques, configuration de la boucle d'exécution.Optimisation du démarrage à froid (--launch -- <chemin_binaire>).
Swift ConcurrencyconcurrencyTâches Swift (créées/en cours d'exécution/suspendues), réentrance d'acteur, utilisation du pool coopératif.Famine async/await, contention d'acteur et tâches longtemps suspendues.
System TracesysTransitions d'état de thread (Running

Skills associés