Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A kód optimalizálása csökkenti a számítási időt és a költségeket. Ez az esettanulmány bemutatja, hogyan használható a Visual Studio profilkészítési eszközeivel a minta .NET-alkalmazások teljesítményproblémáinak azonosítására és megoldására. Ha összehasonlítja a profilkészítési eszközöket, olvassa el Melyik eszközt válasszam?
Ez az útmutató a következőket ismerteti:
- A Visual Studio profilkészítési eszközeinek használata a teljesítmény elemzéséhez és javításához.
- Gyakorlati stratégiák a processzorhasználat, a memóriafoglalás és az adatbázis-interakciók optimalizálásához.
Ezeket a technikákat alkalmazva hatékonyabbá teheti saját alkalmazásait.
Optimalizálási esettanulmány
A minta .NET-alkalmazás lekérdezéseket futtat a blogokat és bejegyzéseket tartalmazó SQLite-adatbázison az Entity Framework használatával. Számos lekérdezést hajt végre, valós adatlekérési forgatókönyvet szimulálva. Az alkalmazás az Entity Framework első lépések mintáján alapul, de egy nagyobb adatkészletet használ.
A fő teljesítményproblémák a következők:
- Magas processzorhasználat: A nem hatékony számítások vagy feldolgozási feladatok növelik a processzorhasználatot és a költségeket.
- Nem hatékony memóriafoglalás: A rossz memóriakezelés túlzott szemétgyűjtéshez és a teljesítmény csökkenéséhez vezet.
- Adatbázis-többletterhelések: A nem hatékony lekérdezések és a túlzott adatbázis-hívások rontják a teljesítményt.
Ez az esettanulmány a Visual Studio profilkészítési eszközeivel rögzíti és kezeli ezeket a problémákat, így hatékonyabbá és költséghatékonyabbá szeretné tenni az alkalmazást.
Kihívás
Ezeknek a teljesítményproblémáknak a kijavítása több kihívást is magában foglal:
- Szűk keresztmetszetek diagnosztizálása: A magas CPU-, memória- vagy adatbázisterhelés kiváltó okainak azonosítása a profilkészítési eszközök hatékony használatát és az eredmények helyes értelmezését igényli.
- Tudás- és erőforráskorlátok: A profilkészítés és az optimalizálás speciális készségeket és tapasztalatokat igényel, amelyek nem mindig érhetők el.
A profilkészítési eszközöket, a műszaki ismereteket és a gondos tesztelést kombináló stratégiai megközelítés elengedhetetlen a kihívások leküzdéséhez.
Stratégia
Ebben az esettanulmányban a megközelítés magas szintű nézete látható:
- Kezdje a CPU-használat nyomkövetésével a Visual Studio CPU-használati eszközével. A Visual Studio CPU-használati eszköze jó kiindulópont a teljesítményvizsgálatokhoz.
- További nyomkövetések gyűjtése a memória- és adatbázis-elemzéshez:
- Használja a .NET objektumfoglalási eszközt a memóriaelemzésekhez.
- Az Adatbázis eszközzel megvizsgálhatja az SQL-lekérdezéseket és az időzítéseket.
Az adatgyűjtéshez a következő feladatok szükségesek:
- Állítsa be az alkalmazást release buildre.
- Válassza ki a CPU-használat eszközt a Performance Profilerben (Alt+F2).
- A Performance Profilerben indítsa el az alkalmazást, és gyűjtsön egy nyomkövetést.
Magas processzorhasználatú területek vizsgálata
Miután összegyűjtöttünk egy nyomvonalat a CPU kihasználtsági eszközzel, és betöltöttük a Visual Studióba, először áttekintjük a kezdeti .diagsession riportoldalt, amely összegzett adatokat jelenít meg. Használja a Részletek megnyitása hivatkozást a jelentésben.
A jelentés részletei nézetben nyissa meg a Hívásfa nézetet. Az alkalmazás legnagyobb processzorhasználattal rendelkező kódútvonalát gyakori elérési útnak nevezzük. A gyakori elérésű útvonal láng ikonja (
) segítségével gyorsan azonosíthatók a javítható teljesítményproblémák.
A Hívásfa nézetben az alkalmazás GetBlogTitleX metódusának magas processzorhasználata látható, amely az alkalmazás processzorhasználatának körülbelül 60% részét használja. A GetBlogTitleX értéke azonban alacsony, csak körülbelül .10%. Ellentétben a teljes CPUértékével, a saját CPU érték kizárja a más függvényekben töltött időt, így távolabb kereshetjük a hívásfában a valódi szűk keresztmetszetet.
GetBlogTitleX külső hívásokat kezdeményez két LINQ-DLL-hez, amelyek a processzoridő nagy részét használják, amint azt a nagyon magas saját PROCESSZOR értékek is bizonyítják. Ez az első jel arra, hogy a LINQ-lekérdezések optimalizálandó területnek bizonyulhatnak.
A vizualizált hívásfa és az adatok eltérő nézetének lekéréséhez nyissa meg a Flame Graph nézetet. (Vagy kattintson a jobb gombbal a GetBlogTitleX, és válassza Nézet a Flame Graph.) Itt is úgy tűnik, hogy a GetBlogTitleX metódus felelős az alkalmazás processzorhasználatának nagy részének (sárga színnel jelenik meg). A LINQ-DLL-ek külső hívásai a GetBlogTitleX mező alatt jelennek meg, és a metódushoz szükséges processzoridőt használják.
További adatok gyűjtése
Gyakran más eszközök is nyújtanak további információkat az elemzéshez és a probléma elkülönítéséhez. Ebben az esettanulmányban a következő megközelítést alkalmazzuk:
- Először is tekintse meg a memóriahasználatot. Lehet, hogy összefüggés van a magas processzorhasználat és a magas memóriahasználat között, ezért hasznos lehet mindkettőt megvizsgálni a probléma elkülönítése érdekében.
- Mivel azonosítottuk a LINQ DLL-eket, az Adatbázis eszközt is megvizsgáljuk.
A memóriahasználat ellenőrzése
Ha meg szeretné tekinteni, hogy mi történik az alkalmazással a memóriahasználat szempontjából, a .NET objektumfoglalási eszközzel gyűjtünk egy nyomkövetést (A C++-hoz használhatja inkább a Memóriahasználat eszközt). A Hívásfa nézet a memóriakövetésben a gyakori elérési utat mutatja, és segít azonosítani a magas memóriahasználatot. Ezen a ponton nem meglepő, hogy a GetBlogTitleX metódus úgy tűnik, hogy sok objektumot hoz létre! Valójában több mint 900 000 objektumfoglalás.
A létrehozott objektumok többsége karakterlánc, objektumtömb és Int32. Előfordulhat, hogy a forráskód vizsgálatával láthatjuk, hogyan jönnek létre ezek a típusok.
A lekérdezés ellenőrzése az Adatbázis eszközben
A Teljesítményprofilozóban a processzorhasználat helyett az Adatbázis eszközt választjuk (vagy mindkettőt). Miután összegyűjtöttünk egy nyomkövetést, nyissa meg a Lekérdezések lapot a diagnosztikai lapon. Az Adatbázis-nyomkövetés Lekérdezések lapján láthatja, hogy az első sorban a leghosszabb lekérdezés látható, 2446 ms. A Rekordok oszlopban látható, hogy hány rekordot olvas be a lekérdezés. Ezeket az információkat későbbi összehasonlításhoz használhatja.
A LINQ által a Lekérdezés oszlopban létrehozott SELECT utasítás vizsgálatával azonosítjuk az első sort a GetBlogTitleX metódushoz társított lekérdezésként. A teljes lekérdezési sztring megtekintéséhez bontsa ki az oszlop szélességét. A teljes lekérdezési sztring a következő:
SELECT "b"."Url", "b"."BlogId", "p"."PostId", "p"."Author", "p"."BlogId", "p"."Content", "p"."Date", "p"."MetaData", "p"."Title"
FROM "Blogs" AS "b" LEFT JOIN "Posts" AS "p" ON "b"."BlogId" = "p"."BlogId" ORDER BY "b"."BlogId"
Figyelje meg, hogy az alkalmazás sok oszlopértéket kér le itt, talán többet, mint amennyire szükségünk van. Nézzük meg a forráskódot.
Kód optimalizálása
Ideje áttekinteni a GetBlogTitleX forráskódot. Az Adatbázis eszközben kattintson a jobb gombbal a lekérdezésre, és válassza a Ugrás a forrásfájlralehetőséget. A GetBlogTitleXforráskódjában az alábbi kód található, amely linq használatával olvassa be az adatbázist.
foreach (var blog in db.Blogs.Select(b => new { b.Url, b.Posts }).ToList())
{
foreach (var post in blog.Posts)
{
if (post.Author == "Fred Smith")
{
Console.WriteLine($"Post: {post.Title}");
}
}
}
Ez a kód foreach ciklusokkal keres az adatbázisban olyan blogokat, amelynek szerzője Fred Smith. Ha megnézzük, láthatjuk, hogy sok objektum jön létre a memóriában: egy új objektumtömb az adatbázis minden blogja számára, az egyes URL-címekhez társított sztringek és a bejegyzésekben található tulajdonságok értékei, például a blogazonosító.
Egy kis kutatást végezünk, és találunk néhány gyakori javaslatot a LINQ-lekérdezések optimalizálásához. Másik lehetőségként időt takaríthatunk meg, és hagyhatjuk, hogy Copilot végezze el a kutatást.
Ha a Copilotot használjuk, a helyi menüben kiválasztjuk Copilot kérése lehetőséget, és beírjuk a következő kérdést:
Can you make the LINQ query in this method faster?
Borravaló
Perjelparancsokat, például /optimize, használhat, hogy segítsen jó kérdéseket megfogalmazni a Copilot számára.
Ebben a példában a Copilot a következő javasolt kódmódosításokat, valamint egy magyarázatot ad.
public void GetBlogTitleX()
{
var posts = db.Posts
.Where(post => post.Author == "Fred Smith")
.Select(post => post.Title)
.ToList();
foreach (var postTitle in posts)
{
Console.WriteLine($"Post: {postTitle}");
}
}
Ez a kód számos módosítást tartalmaz a lekérdezés optimalizálásához:
- Hozzáadta a
Wherezáradékot, és megszüntette az egyikforeachhurkot. - Csak a Cím tulajdonságot vetítettük előre a
Selectutasításban, amire ebben a példában csak szükségünk van.
Ezután újra teszteljük a profilkészítési eszközöket.
Eredmények
A kód frissítése után újra futtatjuk a CPU-használat eszközt a nyomkövetés gyűjtéséhez. A Hívásfa nézet azt mutatja, hogy GetBlogTitleX csak 1754 ms-ot fut, a proceszorra jutó összes CPU idő 37%-át felhasználva, ami jelentős javulás az 59%-hez képest.
Váltson a Flame Graph nézetre, hogy egy másik vizualizáció jelenjen meg, amely a javulást mutatja. Ebben a nézetben GetBlogTitleX a processzor egy kisebb részét is használja.
Ellenőrizze az eredményeket az Adatbázis eszköz nyomkövetésében, és 100 000 helyett csak két rekord van beolvasva ezzel a lekérdezéssel! Emellett a lekérdezés sokkal egyszerűbb, és kiküszöböli a korábban létrehozott szükségtelen LEFT JOIN-illesztéseket.
Ezután újra ellenőrizzük az eredményeket a .NET objektumlefoglalási eszközben, és láthatjuk, hogy GetBlogTitleX csak 56 000 objektumlefoglalásért felelős, közel 95% 900 000-ről!
Ismételni
Előfordulhat, hogy több optimalizálásra van szükség, és a kódmódosításokkal tovább is iterálhatunk, hogy kiderüljön, mely változások javítják a teljesítményt, és segítenek csökkenteni a számítási költségeket.
Következő lépések
Az alábbi cikkek és blogbejegyzések további információkat nyújtanak a Visual Studio teljesítményeszközök hatékony használatának elsajátításához.
- Esettanulmány: Teljesítményproblémák elkülönítése
- esettanulmány: Dupla teljesítmény 30 perc alatt
- A Visual Studio teljesítményének javítása az új mérőeszközzel