Mis on LoC ja kuidas seda mõõta .NET rakendustes?
21.02.2010 | Gunnar
Üks palju kasutatav ja väärkasutatav lähtekoodi mõõtmise meetod seisneb koodiridade arvu loendamises. Mõõdik, millest jutt, kannab nime Lines of Code ehk LoC. Käesolevas postituses annan ülevaate LoC olemusest, selle kasutamisest ja mõõtmisest .NET rakendustes.
Otstarve
LoC näitab kui palju koodilisi käske on rakenduses, nimeruumis, klassis või mõnes muus koodiüksuses – oleneb, mida mõõdeti. Antud mõõdikut kasutatakse peamiselt kahel otstarbel:
- koodiüksuste mõõtmine – näiteks meetodid, mis on pikemad kui 20 käsku, viitavad sellele, et nendesse on koondatud liiga palju vastutusi ja suure tõenäosusega tuleb need meetodid jagada mitmeks pisemaks meetodiks.
- projekti suuruse hindamine – ühe koodibaasi LoC põhjal saab hinnanguid anda väga rangete piirangute all teise väga sarnase koodibaasi kohta. Klassikaline viga, mis tehakse, on see, et võetakse ühe projekti LoC, hinnatakse uus projekt 10x suuremaks ning hinnangud antakse 10x väiksema projekti põhjal kõike 10-ga korrutades.
LoC on projektide hindamiseks üks halvimaid ja ebaefektiivsemaid mõõdikuid. Seda saab kasutada lühidalt hindamisega alustades, kuid see tuleb võimalikult kiiresti asendada mõne täpsema meetodiga.
LoC ei ole lineaarne mõõdik
Statistika tarkvaratööstuses näitab, et LoC ei ole lineaarne mõõdik. Olgu meil hindamise aluseks projekt mille raames kirjutati 10000 rida koodi ja mille peale kulus 13.5 inimkuud. Klassika ütleb, et 10x suurema projekti korral peaks inimkuude arvuks tulema 135, kuid vaadake järgnevat diagrammi! (Näide pärineb Jeff Atwoodi blogi postitusest Diseconomies of Scale and Lines of Code)
Selgub, et 10x suurema projekti korral kulub inimkuid hoopis 170 ja viga lineaarse arvutuse tulemus erineb 35 inimkuu jagu (valetab orienteeruvalt neljandiku jagu). 100x suurema projekti korral kasvab viga veelgi enam.
Projektide hindamiseks soovitan lugeda Steve McConnell’i kustumatut teost Software Estimation - Demystifying the Black Art.
LoC ei ole töötajate efektiivsuse mõõtmiseks
On loodusekaugeid kodanikke läbi maailma ajaloo olnud, kes on püüdnud kasutada LoC töötajate efektiivsuse mõõtmisel. See on räige viga ja äärmiselt loll lähenemine, sest see number ei anna töötajate efektiivsuse kohta mitte mingit infot – LoC arvutamise metoodikad ei arvesta sisse näiteks keerukust ja paljusid muid faktoreid.
Kas programmeerija, kes kirjutab nädalaga valmis 10000 rea pikkuse koodi, on sama efektiivne kui programmeerija, kes tegi sama töö ära sama ajaga, kuid kirjutas 3000 rida? Kas 10000 rida kirjutanud programmeerija on efektiivsem teisest programmeerijast, kes kirjutas nädalaga valmis 100 realise efektiivse implementatsiooni keerukale algoritmile? LoC sellele vastust ei anna.
Loogiline ja füüsiline LoC
LoC jaguneb sõltuvalt mõõtmismeetodist kahte tüüpi:
- loogiline LoC – mõõdetakse kompileeritud koodiüksuseid ning mõõtmise aluseks on kompilaatori poolt loodud kood, mis midagi teeb. Tüüpide definitsioonid, nimeruumide kaasamine jne jäetakse arvestusest välja.
- füüsiline LoC – mõõdetakse lähtekoodi failide analüüsimisel. Sisaldab suurema tõenäosusega vigu, millest loogiline LoC vaba on. Hackles koomiksis on hea näide füüsilise LoC kohta varnast võtta.
Loogiline LoC on parem mõõdik, sest see sisaldab vähem igasugust müra.
LoC mõõtmine .NET projektides
.NET projektide jaoks saab LoC mõõtmiseks kasutada Visual Studio koodi analüüsimise vahendeid. Teiseks variandiks on NDepend, mis on professionaalidele mõeldud tarkvara. Selle abil on võimalik koodi palju efektiivsemalt ja mugavalt analüüsida.
Sama koodi kohta annavad nad küllaltki erinevad tulemused, sest arvutusmeetodid on erinevad:
- Visual Studio – annab tulemuseks ligikaudse arvu koodiridu, mis baseerub vahekeele (Intermediate Language – IL) koodil, mille on kompilaator tootnud (täpsema kirjelduse leiab MSDN-i artiklist Code Metrics Overview),
- NDepend – arvutab tulemused PDB-failide põhjal ning loeb koodiridadeks kõikides meetodites leiduvad sequence point’id. Et parem pilt sequence point’idest saada, siis soovitan lugeda Rick Byers postitust DebuggingModes.IgnoreSymbolStoreSequencePoints.
Erinevustest parema pildi saamiseks vaatame järgnevat klassi.
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
}
Ja tulemused on siin.
Visual Studio pakub lihtsa klassi korral LoC väärtuseks 9, NDepend aga 1 (see on FullName omaduse keha). Parema idee saamiseks vaadake korra, mis asja toodab kompilaator automaatsest omadusest. Lühida ülevaate annab minu postitus Kas automatic property on sama mis property?
Oma sisemuselt on automaatne omadus sarnane tavalisele ja loomulikult genereeritakse ka selle jaoks IL instruktsioonid, kuid PDB-failidesse sequence point’e ei looda, sest getter ja setter on kompilaatori poolt automaatselt genereeritud kehaga. Visual Studio sellele tüngale pihta ei saa, sest IL instruktsioonid on olemas. NDepend neid omadusi aga koodiridade loendamisel ei näe. Samuti on Visual Studio sisse arvestanud klassi vaikimisi konstruktori, mida ma koodis ei defineerinud.
NDepend päringud
Lisaks kiirelt genereeritavatele raportitele võimaldab NDepend luua ka päringuid, mille abil saab koodiüksusi LoC järgi leida. Näiteks need kaks päringut:
SELECT METHODS WHERE NbLinesOfCode> 100
Esimene neist tagastab meetodid, mille keha koodiridade arv ületab 20 ja teine tagastab katastroofi lähtekoodis – koodiridade arv on meetodites äärmiselt suur.
Kokkuvõte
LoC on lähtekoodi mõõdik, mida on mõttekas kasutada liiga suurte koodiüksuste leidmiseks. Kuigi seda saab piiratud ulatuses kasutada ka projekti suuruse hindamisel, on see ohtlik tee, mida minna ja LoC pealt tuleb hindamisel võimalikult kiiresti liikuda üle põhjalikumatele ja täpsematele hindamismeetoditele. Töötajate efektiivsuse hindamine LoC põhjal pole võimalik ja vastav tegevus klassifitseerub jaburuseks.
.NET rakendustes aitavad LoC mõõta Visual Studio koodianalüüsi vahendid ja NDepend. Viimane neist on professionaalidele suunatud vahend, mida saab siduda ka integratsiooniserveritega. Kumba kasutada – sõltub kasutaja enda soovidest ja vajadustest. Mina kasutan praegu NDependi ja olen sellega väga rahul, sest saan infot lähtekoodi kohta hulka enam kui Visual Studio vahenditega.
