Freigeben über


Profilieren Ihrer App mit GitHub Copilot Profiler Agent

Der GitHub Copilot Profiler Agent arbeitet zusammen mit GitHub Copilot und führt Sie durch Leistungstests und Verbesserungen.

In diesem Lernprogramm wird gezeigt, wie Sie Anwendungen profilieren und die Leistung mithilfe des Copilot Profiler-Agents verbessern.

Der Profiler-Agent kann alle folgenden Aufgaben ausführen.

  • Analysieren der CPU-Auslastung, Speicherzuweisungen und Laufzeitverhalten.
  • Engpässe bei der Surface-Leistung.
  • Generieren Sie BenchmarkDotNet Benchmarks , oder optimieren Sie vorhandene BenchmarkDotNet-Benchmarks.
  • Wenden Sie vorgeschlagene Optimierungen an.
  • Überprüfen sie Verbesserungen in einer geführten Schleife.

Der Profiler-Agent ist besonders hilfreich, wenn:

  • Sie sind mit Profilerstellung nicht vertraut.
  • Sie sind nicht sicher, wo Sie mit der Leistungsoptimierung beginnen.
  • Sie möchten Optimierungen mit echten Benchmarks überprüfen.
  • Sie arbeiten an leistungsstarken Apps wie Spielen, Diensten oder Clienttools.

Informationen zu anderen Profilerstellungsfeatures in Copilot finden Sie in KI-erweiterten Szenarien. Allgemeine Informationen zu Copilot-Agents und zum Agent-Modus finden Sie unter Verwenden des Copilot-Agent-Modus.

Voraussetzungen

Um zu beginnen, benötigen Sie Folgendes:

Starten einer Profilerstellungssitzung

  1. Erstellen Sie in Visual Studio eine neue C#-Konsolen-App.

    Wählen Sie im Startfenster Neues Projekt erstellen aus. Geben Sie die Konsole in das Suchfeld ein, wählen Sie C# als Sprache aus, und wählen Sie dann "Konsolen-App für .NET" aus. Wählen Sie Weiteraus. Geben Sie einen Projektnamen wie ConsoleApp_CopilotProfile ein, und wählen Sie "Weiter" aus. Wählen Sie ein Zielframework (z. B. .NET 8) und dann "Erstellen" aus.

  2. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten "Abhängigkeiten " im Projekt, wählen Sie "NuGet-Pakete verwalten", suchen Sie nach EntityFramework, und fügen Sie dem Projekt dann die folgenden Pakete hinzu:

    • Microsoft.EntityFramework.Core
    • Microsoft.EntityFramework.Core.InMemory

    Die App verwendet eine In-Memory-Datenbank, um die Projekteinrichtung zu vereinfachen.

  3. Ersetzen Sie den Code in Program.cs durch den folgenden Code:

    using System.Diagnostics;
    using Microsoft.EntityFrameworkCore;
    
    // Configure EF Core to use the InMemory provider
    var options = new DbContextOptionsBuilder<AppDbContext>()
        .UseInMemoryDatabase("PerfDemoDb")
        .Options;
    
    using var db = new AppDbContext(options);
    
    // Seed 100,000 records once
    if (!db.People.Any())
    {
        var rand = new Random(42);
        var cities = new[]
        {
            "Chicago", "Seattle", "Cairo", "London", "Paris",
            "Cleveland", "Calgary", "Dallas", "Berlin", "Copenhagen"
        };
    
        var people = Enumerable.Range(1, 100_000).Select(i => new Person
        {
            Name = $"Person {i}",
            Age = rand.Next(18, 80),
            City = cities[rand.Next(cities.Length)]
        });
    
        db.People.AddRange(people);
        db.SaveChanges();
    }
    
    Console.WriteLine($"Seeded records: {db.People.Count():N0}");
    
    // Inefficient LINQ pattern: materialize everything and repeatedly re-materialize + chain ToList
    // This simulates client-heavy work that doesn't scale, even with in-memory provider
    var sw = Stopwatch.StartNew();
    
    // Full materialization of all rows
    var all = db.People.ToList();
    
    // Extra ToList calls create multiple large intermediate lists
    var inefficient = all
        .Where(p => p.Age > 50)
        .ToList()
        .Where(p => p.City.StartsWith("C"))
        .ToList()
        .Select(p => p.Name)
        .Distinct()
        .OrderBy(n => n)
        .Take(10)
        .ToList();
    
    sw.Stop();
    Console.WriteLine($"Inefficient query returned {inefficient.Count} rows in {sw.ElapsedMilliseconds} ms");
    
    // EF Core entity
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public int Age { get; set; }
        public string City { get; set; } = string.Empty;
    }
    
    // EF Core DbContext
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
        public DbSet<Person> People => Set<Person>();
    }
    
  4. Wählen Sie "Buildlösung > erstellen" aus, um sicherzustellen, dass die App ohne Fehler erstellt wird.

Fragen Sie Copilot nach Profilerstellungs-Insights

  1. Öffnen Sie das Copilot-Chatfenster, und verwenden Sie die folgende Eingabeaufforderung.

    @Profiler Please evaluate the performance of this code

  2. Wählen Sie "Senden" aus.

    Der @Profiler Befehl ruft den Copilot Profiler-Agent auf.

    Screenshot des Aufrufens des Profiler-Agents.

    Alternativ können Sie den Profiler-Agent starten, indem Sie manuell "Tools auswählen" auswählen und den Profiler-Agent manuell aktivieren und dann in den Agentmodus wechseln. Bei Verwendung dieser Methode müssen Sie den @Profiler Befehl nicht verwenden.

    Copilot fragt, ob Sie den Profiler ausführen möchten.

    Screenshot der Profilerstellungsanforderung starten.

  3. Wählen Sie "Bestätigen" aus.

    Der Agent führt eine Reihe von Schritten unabhängig durch. Es untersucht den Code, fügt unterstützung für das Projekt für BenchmarkDotNet hinzu, einschließlich Projektverweise und Pakete, fügt Benchmarks zu einer neuen Datei hinzu und führt Vergleichstests mit neuem Code aus, der generiert wird.

    Benchmarkergebnisse werden im Ausgabefenster angezeigt, wobei die Ausgabe auf Diagnostics Hub festgelegt ist.

    Screenshot der Benchmark-Ausgabe.

    Ergebnisse aus der Diagnosesitzung werden in einem Diagsession-Dateibericht angezeigt. Wenn Sie die CPU-Auslastung manuell untersuchen möchten, lesen Sie " Analysieren der Leistung mithilfe von CPU-Profilerstellung". In diesem Szenario verwenden wir stattdessen den Profiler-Agent.

    Nach Abschluss des Tests fasst der Agent seine Ergebnisse zusammen.

    Der Agent meldet einen potenziellen 33% Effizienzgewinn, hauptsächlich durch Entfernen der Materialisierung von Volltabellen und einem unnötigen ToList() Methodenaufruf.

    Screenshot der Testergebnisse.

    Der Agent bietet außerdem einige Vorschläge für die nächsten Schritte, einschließlich einer Option zum Optimieren der LINQ-Abfrage.

    Screenshot von Codevorschlägen.

    In diesem Beispiel konzentrieren Sie sich auf die Optimierung der LINQ-Abfrage.

  4. Wählen Sie den zweiten Copilot-Vorschlag und dann "Senden" aus, um dem Agent mitzuteilen, dass die LINQ-Abfragekette optimiert wird.

    Der Agent aktualisiert Program.cs und bietet zusätzliche Vorschläge zum Optimieren von Code. Wir werden diese Vorschläge jetzt überspringen.

  5. Sehen Sie sich Codeänderungen in Program.cs an.

    Screenshot der Codeänderungen.

  6. Überprüfen Sie unten rechts im Code-Editor die Codeänderungen, und wählen Sie "Beibehalten" aus, um sie beizubehalten.

    Die optimierte Abfrage wird hier angezeigt.

     var optimized = db.People
         .AsNoTracking()
         .Where(p => p.Age > 50 && p.City.StartsWith("C"))
         .Select(p => p.Name)
         .Distinct()
         .OrderBy(n => n)
         .Take(10)
         .ToList();
    
  7. Wenn Sie agentieren möchten, um zusätzliche Optimierungen vorzunehmen, wählen Sie entweder die vom Agenten bereitgestellten Vorschläge aus, oder stellen Sie weitere Fragen.

Chat fortsetzen, nachdem das Tokenlimit erreicht wurde

Der Profiler-Agent bietet eine intelligente Zusammenfassung und Fortsetzung des Chat-Threads, die entwickelt wurde, damit Ihre Arbeit fließend bleibt, ohne durch das Erreichen von Token-Grenzen blockiert zu werden.

Wenn ein Chat mit Copilot seine Token-Obergrenze erreicht, haben Sie die Möglichkeit, eine Zusammenfassung zu erstellen und in einem neuen Thread fortzufahren.

Screenshot der Threadzusammenfassung.

Wenn Sie diese Option auswählen, generiert der Agent automatisch eine präzise, kontextreiche Zusammenfassung des aktuellen Chatthreads und führt ihn in eine neue Unterhaltung weiter. Auf diese Weise können Sie vermeiden, alle Schritte nachzuverfolgen.