ABONAMENTE VIDEO REDACȚIA
RO
EN
×
▼ LISTĂ EDIȚII ▼
Numărul 1
Abonament PDF

Performanţa în aplicaţiile .NET

Flaviu Mățan
Principal Software Engineer
@IXIA
PROGRAMARE

Dinamica modernă a dezvoltării de aplicaţii software cu focus pe livrări frecvente de cod funcţional face ca performanţa să fie un aspect adesea trecut cu vederea.

Cu toate că abordarea de genul "fă-l să meargă întâi după aceea refactorizam" are avantaje demonstrate cum ar fi adaptarea uşoara şi rapidă la modificările de cerinţe, ea deschide uşa adesea codului scris neglijent care afectează performanţa într-un mod negativ.

Fie că este inclusă din start în ciclul de dezvoltare, sau este cauzată de situaţii cum ar fi descoperirea de operaţii foarte lente sau o degradare abruptă de performanţa în anumite scenarii (ex. creşterea numărului de puncte de intrare cum ar fi numărul de useri care folosesc un sistem etc.) sau ca un pas premergator unui task de scalabil-itate, măsurarea performanţei aplicaţiilor devine un pas din ce în ce mai important în viaţa unei aplicaţii.

Acesta este primul dintr-o serie de articole despre performanţa în aplicaţiile .NET şi acoperă partea de alegere a profiler-ului potrivit. Al doilea articol din serie va fi un studiu de caz în care vor fi analizate câteva surse comune de degradare de performanţa precum şi posibile soluţii la aceste probleme.

Alegerea profiler-ului potrivit

Detectarea problemelor de performanţă ale unei aplicaţii se poate face prin diferite metode, de la caz la caz, începând cu folosirea ceasului de mână pentru a măsura timpul de execuţie al unor operaţii, adăugarea de timere în cod în jurul operaţiilor suspecte de probleme de performanţă şi logarea acestora în fişiere pâna la folosirea aplicaţiilor dedicate, aşa-zisele profiler-e, care furnizează date complexe colectate la rularea aplicaţiei pe baza cărora programatorii pot să identifice zonele cu probleme reale de performanţă cu un efort relativ mic.

Prima variantă este folosită cu succes de către managementul superior pentru evaluarea aplicaţiei dpdv al performanţei.

A doua variantă în care se folosesc timer-e presarăte prin codul sursa funcţionează bine atunci când problema de performanţa este ştiută şi relativ locali-zata şi se vrea obtinerea mai exacta a cauzei acesteia. Procedeul este de obicei unul secvential, în mai multi pasi care duce într-un final la identificarea codului prob-lema.

În prima parte a acestei serii de articole dedicate performanţei în aplicaţiile .NET vom discuta despre a treia variantă de investigare, cea în care se folosesc aplicaţii de tip performance profiler deoarece acestea pun la dispozitia programa-torilor date şi unelte ce facilitează identificarea, fixarea şi reevaluarea problemelorde performanţa. În plus devii automat un programator cool, daca le folosesti.

În continuare vom pune faţă în faţă două dintre cele mai folosite profiler-e comerciale pentru aplicaţii .NET şi anume ANTS Performance Profiler de la Redgate respectiv dotTrace Performance de la Jet-Brains. Cautarea în google dupa ".net per-formance profiler" va întoarce cele două profiler-e în primele 2 rezultate.

Le vom evalua în funcţie de o serie de criterii între care: uşurinţa în folosire, acurateţea măsuratorilor, analiza rezultate-lor, preţ etc.

Uşurinţa în folosire

Ambele aplicaţii sunt foarte similare în ce priveste partea de inițiere a sesiunii de profiling.

Fiecare oferă posibilitatea de a alege tipul aplicaţiei de analizat (standalone, sil-verlight, web etc.) şi optiunile legate de nivelul de detaliu al datelor colectate (la nivel de linie, metoda sau sampling).

În continuare sunt descrise cele mai importante optiuni de profiling. Majori-tatea sunt prezente sub o denumire sau alta în ambele aplicaţii:

Modul de profiling:

Sampling - este o metoda de măsurare de mica acurateţe prin care o data la un anumit interval de timp se suspendă toate thread-urile aplicaţiei analizate şi profiler-ul obtine call stack-ul fiecărui thread. Pe baza call stackurilor colectate în timp profiler-ul va putea estima duratele apelurilor prezente în stack-uri la diferite momente de timp.

Avantajul acestei metode este ca influentează cel mai putin aplicaţia anali-zata, aceasta funcţionand foarte apropiat de performanţele ei normale. Dezavantajele sunt acurateţea mică a măsurătorilor şi lipsa hitcount-ului pentru funcţii. Opțiunea este prezentă în ambele profiler-e.

Tracing sau la nivel de metoda - aceasta este cea mai folosita metoda în care măsuratorile se fac pe baza notificărilor venite din partea CLR (Common Language Runtime) la intrarea respectiv ieșirea din funcţii.

Avantajele includ o acurateţe foarte mare a măsurării timpului petrecut în funcţii şi prezenta hitcount-ului pentru toate funcţiile.

Dezavantajul major este că influentează într-o măsura destul de mare performanţa aplicaţiei analizate.Opțiunea este prezenta în ambele profilere.

Notă: ANTS Performance Profiler are optiune (activa by default) prin care se ajustează automat durata funcţiilor scăzând influenta estimată a profiler-ului asupra ex-ecutiei acestor funcţii.

La nivel de linie - acest mod pro-duce cele mai detaliate rezultate ce conțin informații legate de durata şi hitcount la nivel de linie de cod executată. Principalul dezavantaj este influenta majora adusă aplicaţiei analizate. Optiunea este prezenta în ambele profilere.

2. Metoda de măsurare:

Wall time - reprezintă timpul total scurs între intrarea şi iesirea dintr-o funcţie. Acest mod înregistrează inclusiv timpul în care thread-ul îl petrece în operaţii de sleep, wait, join etc.

CPU time (sau thread time) - în acest mod se înregistrează doar timpul în care un thread consuma efectiv procesor. Tim-pul petrecut în operaţii de sleep, wait, join nu sunt incluse în măsurătoarea finala a funcţiei.

3. Alte opțiuni

Ajustarea timpilor pentru a compensa influenta profiler-ului - daca opțiunea este activă, din durata măsurată a funcţiilor se scade automat durata estimată a influenței profiler-ului asupra executiei.

Nota asupra notatiei din tabel: Da* în-seamna preferința autorului între cele două oferte.

Obtinerea rezultatelor

Cele două applicații au moduri diferite pen-tru a obtine datele de profiling între două momente de timp: ANTS Performance Pro-filer 6.3 are notiunea de timeline (linie a tim-pului), iar dotTrace Performance folosește noțiunea de snapshot.

ANTS Profiler timeline

Timeline-ul trebuie să recunoaștem că este un control sofisticat şi spectaculos.

Acesta se actualizează în timp real pe măsura ce aplicaţia analizată rulează şi ofera informatii cum ar fi graficul încărcării procesorului, citiri/scrieri I/O, excepții şi evenimente UI ce au avut loc pe parcursul rularii.

Timeline-ul este interactiv, permițând selectarea de ferestre, zoom in/out, click pe exceptii şi evenimente pentru a obține informatii adiționale despre acesta cât şi salvarea selecțiilor (ferestrelor) sub forma de bookmark-uri.

Ferestre

Selectarea unei ferestre pe timeline va actu-aliza datele colectate din fereastra de analiza pe intervalul determinat de fereastra. Fere-strele se pot construi astfel încât să cuprin-da o anumita operaţie, un spike CPU sau intreaga fereastra.

Selectarea unei ferestre în jurul unei anumite operaţii poate fi mai complicată decât pare, deoarece presupune memorarea/identificarea punctului în care a început operaţia. Succesiunea de acțiuni ar fi după cum urmeaza: suntem pe cale să executam operaţie în aplicaţia analizată pentru care dorim să colectăm date de profiling,marcăm timeline-ul (vizual sau cu o fereastra temporara de ex.) chiar înainte de a porni operaţia, dăm drumul la operaţie, la finalul acesteia trasam fereastra de la punctul de pornire stabilit anterior pâna la sfârșitul timeline-ului (dacă marcarea punctului de început s-a făcut folosind o fereastra temporară, aceasta se poate extinde pâna la punctul final folosind mouse-ul). O singură fereastra poate fi selectată la un moment dat. Dimensiunea acesteia poate cuprinde orice subset din timeline.

Bookmark-uri

Acestea se salvează împreună cu salvarea datelor de profiling. Bookmark-urile sunt foarte utile atunci când vrem să revenim asupra unor rezultate de profiling salvate anterior şi dorim să revedem datele de profiling pentru anumite operaţii sau zone interesante. În absenta bookmark-urilor ar trebui să refacem selectiile (ferestrele) corespunzătoare operaţiilor căutate pe baza informatiilor din timeline (grafic CPU, evenimente etc.). Folosind bookmark-uri pentru a marca ferestrele relevante la momentul în care le selectam pentru prima dată ne permite refacerea ferestrelor cu un singur click pe timeline în suprafata bookmark-ului. Cei de la JetBrains au rezolvat problema asta folosind notiunea de "snapshot" care structurează în mod automat datele colectate pe intervale stabilite de către utilizator.

Pro şi Contra

Avantajele timeline-ului includ: flexibilitate maxima în selectarea ferestrelor de timp de orice dimensiune, informatii aditionale gen exceptii şi evenimente.

Dintre dezavantaje:

- greu de trasat ferestre în jurul unor operaţii bine delimitate

- colectarea de date este activa pe tot parcursul rularii (influentand performanţa aplicaţiei analizate).

dotTrace snapshot

dotTrace Performance are un mod mai simplu de colectare a datelor sub forma de capturi (snapshot-uri). Astfel programatorul alege momentul exact în care începe colectarea datelor de profiling şi momentul în care se opreste, rezultatul reprezentand un snapshot (captura). Un snapshot este de sine statator şi nu poate fi combinat cu alte snapshoturi.

Pro şi Contra

Avantaje:

- colectarea datelor este activă doar pe durata capturii reducand astfel impactul asupra performanţei aplicaţiei analizate (notă: Impactul asupra aplicaţiei analizate în perioadele în care nu exista snapshot ac-tiv nu sunt zero. Procesul este instrumentat şi toate hook-urile active, doar colectarea şi structurarea datelor de profiling este sistata).

- colectarea de date pentru anumite operaţii se face usor (start/stop snapshot)

Dezavantaje:

- snapshot-urile nu pot fi extinse sau restranse (ca şi la timeline)

Analiza rezultatelor

Ambele aplicaţii pun la dispoziția utilizatorului un arsenal de funcţionalități care să faciliteze gasirea problemelor de performanţe ale aplicaţiilor analizate.

Exista elemente de bază, comune celor două profiler-e cum ar fi folosirea aceluiasi set de metrici (numar de apeluri, durata metodelor incluzând sau nu duratele funcţiilor apelate în cadrul lor), evidențierea celor mai costisitoare metode, filtrarea metodelor cu impact foarte mic, mapare la codul sursa etc. şi există elemente distincte şi utile de-o parte şi de alta în ce priveste modurile de prezentare şi grupare a metodelor, posibilitatile de căutare şi adnotare etc.

2.1 Moduri de vizualizare al rezultatelor

Grupate per thread

Ambele aplicaţii afișează by default stack trace-urile sub forma arborescenta, per thread, ordonate descendent dupa durata. Se poate observa ca cele două reprezentari sunt similare dpdv al structurii informatilor (funcţii, durata, hitcount) cat şi al continutului, cele două profilere afisând aproximativ acelasi stack (aceeași succesiune de metode).

Definiții:

Call stacks - pentru fiecare thread sunt înregistrate toate call stack-urile exercitate de-a lungul executiei în cadrul acelui thread. Notă: ambele profiler-e filtrează metodele irelevante (cu durată foarte mica) din stack-urile afisate. Utilizatorul poate opta pentru suspendarea filtrarii în ambele cazuri.

Procent - aportul unei metode la durata totala a thread-ului, exprimat în procente. Procentul metodei cuprinde durata acelei metode plus durata tuturor metodelor apelate de aceasta.

Notă: La dotTrace acest procentaj apare intotdeauna în afisarea arborescenta. În cazul profiler-ului de la ANTS exista o coloana care se numeste "Time with children" iar valorile ei pot fi exprimate la alegere în pro-cent, milisecunde sau secunde.

Timpul metodei (time) - reprezinta durata proprie a unei metode fara a lua în calcul şi eventualele metode pe care le apeleaza. Notă: în vizualizarea sub forma arbores-centa doar ANTS Performance Profiler are această coloana.

Timpul impreuna cu metodele apelate (time with children) - vezi descrierea de la Procent mai sus.

Hitcount - reprezintă de câte ori a fost apelată o metoda într-un anumit stack. Daca o metoda apare în stack-uri diferite ea va avea foarte probabil valori diferite.

Pe lângă modul default cu grupare per thread, sub forma arborescentă prezentat mai sus, fiecare profiler mai are şi alte moduri de prezentare/grupare al funcţiilor din rezultate.

Flat List

Ambele au modul flat list în care funcţiile nu mai sunt grupate după vreun criteriu (cum ar fi per thread), ci sunt listate şi sortate după un anumit crtiteriu (ex. descrescător după durata, hitcount, nume).

În acest mod se pot afla funcţiile cele mai costisitoare dpdv a duratei şi al apelurilor. Dacă o anumita metoda este apelată în mai multe stack-uri (thread-uri), în vizualizarea flat list metoda va apărea o singura dată şi va avea durata şi numarul de apeluri cumulat pentru toate contextele în care este apelată.

2.2 Drill down

Odată identificată o funcţie suspectă vom dori să "săpam" pâna ajungem la cauza principala a duratei acelei metode. În modul arborescent per thread se permite navigarea în jos deschizând rând pe rând funcţiile apelate.

Este o operaţie foarte comună ce poate deveni frustrantă dacă trebuie să mergem "din click în click" mai ales în situațiile în care stack-ul este foarte adanc.

Cei de la ANTS au rezolvat simplu problema oferind o optiune de expandare automată a celei mai costisitoare cale din stack pornind de la funcţia selectata.

Din păcate, în dotTrace Performance 4.5.1 nu exista o astfel de opțiune fiind nevoit să transpiri ceva mai mult pentru a ajunge jos, la baza stack-ului.

În ANTS Performance Profiler 6.3 pentru o anumită funcţie putem deschide modul grafic de reprezentare arborelui de apeluri avand metoda de pornire ca şi rădăcina.

Acest mod de vizualizare oferit de profiler-ul de la ANTS este unul care pe langa ca arată foarte bine, este şi foarte util în gasirea problemelor de performanţa. în plus este şi foare prietenos dpdv al modului de folosire, expandarea unui nod în funcţiile apelate din acesta facandu-se cu un singur click.

Modul grafic este lansat dintr-una din-tre celelalte două vizualizari (cel grupat per thread respectiv cel de tip lista) prin selec-tarea unei metode şi alegerea reprezentarii de tip call graph din meniul contextual. Pornind de la funcţia selectata, arborele de apeluri de metode poate fi expandat atat în jos inspre funcţiile apelate cat şi în sus afisand metodele apelante.

O optiune foarte utila va expanda automat în jos arborele celor mai costisitoare funcţii apelate permitand analiza celui mai costisitor sub-stack.

Exista şi în aceasta vizualizare filtrare asupra metodelor cu impact mic dpdv al timpului ocupat, dar este mai permisiv decat în varianta de vizualizare arborescenta per thread. Adică metode care apar în arborele grafic de funcţii pot lipsi din varianta per thread. Acest lucru face ca de cele mai multe ori analiza să ajungă în acest mod.

Un alt aspect foarte important al acestei variante de afisare este faptul că există optiunea de a exporta graficul în format pdf sau imagine oferind un mod foarte facil de a împărtăși rezultatele altor persoane.

Echivalentul în dotTrace Performance ar deschiderea unei metode într-un tab nou, dedicat acesteia.

Ambele abordari (si cea de la ANTS şi cea de la JetBrains) prezintă aceleasi informații şi duc în mod normal la aceleasi rezultate. Varianta de la ANTS face totuși arborele de apeluri mai usor de navigat (mai ales în cazul unor ierarhii stufoase) prin optiunile de "expandare cale costisitoare" şi posibilitatea de zoom in/out oferită.

Căutarea

Cautarea unei metode este o funcţie destul de folosita pe parcursul analizei rezultatelor de profiling în special atunci când stim exact ce metoda urmarim sau când dorim să vedem efectele optimizărilor efectuate asupra anumitor metode.

La acest capitol dotTrace sta mai bine oferind un control de search avansat care prezintă o lista de sugestii de metode pe măsura ce se tastează numele funcţiei cautate:

ANTS a preferat un control simplist, fără sugestii, fără cautare bazată pe names-pace.

Comparare de rezultate

Doar dotTrace Performance 4.5.1 oferă posibilitatea de a compara rezultatele obținute în două sesiuni de profiling diferite prin funcţia de comparare a două snapshot-uri.

Este o funcţionalitate pe care trebuie să recunosc că am folosit-o foarte rar (o dată sau de două ori) din cauză că pentru a avea o comparatie relevantă şi ușor de interpretat ar trebui ca cele două snapshot-uri să fie cât mai apropiate dpdv al succesiunii de apeluri precum şi al numărului de apeluri.

În conditii optime rezultatul comparatiei poate fi foarte util în a determina efectele unei eventuale optimizari asupra performanţei.

Posibilitati de adnotare/marcare

O alta funcţionalitate oferită doar de dot-Trace Performance este cea de adnotare/marcare a metodelor. Utilizatorul poate adăuga comentarii pentru anumite metode şi poate scoate în evidență o anumita metoda prin schimbarea formatarii şi culorii.

Doar profiler-ul de la JetBrains ofera astfel de funcţionalitate prin intermediulfuncţiei de Adjust Time din meniul contextual pentru o metodă. Ajustarea se poate face reducand durata de la 100% la un procent care reprezintă durata estimată a me-todei în urma unei eventuale optimizări. Ajustarea se poate aplica doar la stack-ul curent sau la toate stack-urile în care apare metoda respectivă.

Afectarea performanţei aplicaţiei analizate

Ambele profiler-e influențează aplicaţia pe care o analizează în funcţie de modul de profiling folosit atat în termeni de performanţa cat şi de memorie.

În tabelul din dreapta se gasesc măsuratori de performanţa facute asupra unei aplicaţii de test (aplicaţia Demo din kitul de dotTrace Performance 4.5.1)

Din măsuratorile din tabel se pot trage câteva concluzii evidente:

- în modul sampling ambele profiler-e influentează nesemnificativ aplicaţia analizata

- în modul tracing (sau la nivel de metoda) rularea cu dotTrace este durează ceva mai mult decat cu ANTS.

- cu modul de profiling la nivel de metoda lucrurile stau foarte diferit, rularea cu dotTrace fiind de mai bine de 3 ori mai lenta. De notat faptul ca se pot aplica filtre prin care se specifica ce module/clase/funcţii sunt incluse sau excluse din analiza la nivel de linie.

- urmatoarele două moduri sunt dis-ponibile doar la dotTrace Performance Pro-filer şi sunt foarte importante atunci când se doreste analiza unei anumite operaţii. În acest scenariu se poate opta pentru pornirea aplicaţiei în profiler fără însă a porni colec-tarea de date de profiling. Acest lucru face ca aplicaţia analizată să se "miște" mult mai bine (in modul tracing fiind semnificativ mai rapid decat ANTS). Avantajul acestui mod este şi mai evident atunci când pâna să se ajungă să se execute operaţia dorita au loc niste operaţii costisitoare ca timp de proc-esare (deschiderea unui fișier mare).

Influența asupra memoriei folosite de catre procesul analizat este şi ea semnificativa putând să ajungă la până de 3 ori mai mare decat în varianta fără profiler atașat. Asta inseamnă că profiling-ul aplicaţiilor mari consumatoare de memorie se poate termina cu excepții de tip Out Of Memory. Amble profilere au influență asupra memoriei apropiata. O alta influență (nedocumentata) pe care profiler-ele o au asupra aplicaţiilor analizate este asupra timing-ului threadurilor şi anume, pot să scoată la iveala bug-uri de sincronizare de thread-uri (cum ar fi race conditions şi dead locks) care până atunci nu s-au manifestat.

Complexitatea aplicaţiilor analizate

Din experienta cu ambele profiler-e pot spune ca ANTS Performance Profiler 6.3 este mai limitat decât dotTrace Performance 4.5.1 în sensul că la anliza unor aplicaţii desktop foarte complexe (din punct de vedere a memoriei consumate şi utilizare CPU), interfata utilizator (în special partea de timeline) raspunde din ce în ce mai greu la interacțiunea utilizatorului.

De asemnea, în cazul aplicaţiilor complexe, profiler-ul de la ANTS ajunge câteodată să nu mai afiseze corect controalele din interfața (afisand un X roșu mare). A trebuit să recurg la dotTrace pentru a face profiling pe o astfel de aplicaţie.

Alte Criterii

Profiling I/O şi SQL

- doar la ANTS Performance Profiler

6.3. Funcţionalitatea este oferita doar pentru sisteme de operare mai noi decat Windows XP şi doar în varianta Professional Portabilitatea rezultatelor şi analiza ulterioara

- ANTS oferă posibilitatea de a exporta un set intreg de rezultate de profiling în formatele html şi xml. Se poate de asemenea exporta reprezentarea grafică a arborelui unei metode

- dacă se dorește transportarea rezultatelor în formatul binar pentru a putea fi deschise pe alte masini, probabil că acesta va fi mai usor pentru rezultatele obtinute cu dotTrace deoarece fiecare snapshot se salvează în fisier separat spre deosebire de ANTS unde întreaga sesiune de profiling se salvează într-un singur fisier. Desigur că cele două pot deveni echivalente în cazul în care avem un singur snapshot mare în cazul dotTrace ce corespunde intregii sesiuni de profiling. De obicei nu este cazul.

Abilitatea de atasare la un proces

- ANTS Performance Profiler 6.3 ofera optiunea atasarii la un proces ce rulează .NET Framework 4.0. dotTrace Performance 4.5.1 nu are din păcate opțiuni de atașare.

Integrare cu Visual Studio

- ambele profilere se integrează cu Visual Studio permitând lansarea sesiunii de profiling direct din IDE

Concluzie

ANTS Performance Profiler 6.3 - 17 puncte

dotTrace Performance 4.5 - 16 puncte

Ambele profiler-e vă vor ajuta cu succes să rezolvați problemele de performanţă din aplicaţiile dumneavoastra. Fiecare are puncte ei forte care nu se găsesc la cealaltă şi oferă funcţionalitatea de bază la nivele egale.

În funcţie de specificul aplicaţiei de analizat va veti putea orienta către una sau către cealaltă. Sfatul meu este să le incercati pe amândouă pentru a va face o idee mai buna despre ce ofera fiecare şi care vi s-ar potrivi cel mai bine.

Puteti descarcă versiunile trial pentru cele două profiler-e de la locațiile de mai jos: dotTrace Performance Profiler 4.5 si ANTS Performance Profiler 6.3

Sponsori

  • comply advantage
  • ntt data
  • 3PillarGlobal
  • Betfair
  • Telenav
  • Accenture
  • Siemens
  • Bosch
  • FlowTraders
  • MHP
  • Connatix
  • UIPatj
  • MetroSystems
  • Globant
  • Colors in projects