Sveiki visiem! Å is raksts ir paraugprakses apkopojums, ko es un mani kolÄÄ£i jau ilgu laiku esam izmantojuÅ”i, strÄdÄjot pie dažÄdiem projektiem.
InformÄcija par maŔīnu, uz kuras tika veikti aprÄÄ·ini:BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i5-8250U CPU 1.60 GHz (Kaby Lake R), 1 CPU, 8 loģiskie un 4 fiziskie kodoli
.NET Core SDK=3.0.100
[Saimniekdators]: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64 bitu RyuJIT
Kodols: .NET Core 2.2.7 (CoreCLR 4.6.28008.02, CoreFX 4.6.28008.03), 64 bitu RyuJIT
[Saimniekdators]: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64 bitu RyuJIT
Kodols: .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64 bitu RyuJIT
Darbs=Core Runtime=Core
ToList vs ToArray un cikli
Es plÄnoju sagatavot Å”o informÄciju, izlaižot .NET Core 3.0, bet viÅi mani pÄrspÄja, es nevÄlos nozagt kÄda cita slavu un kopÄt citu informÄciju, tÄpÄc es tikai norÄdÄ«Å”u saite uz labu rakstu, kur ir sÄ«ki aprakstÄ«ts salÄ«dzinÄjums.
SavÄ vÄrdÄ es tikai vÄlos iepazÄ«stinÄt jÅ«s ar saviem mÄrÄ«jumiem un rezultÄtiem; es tiem pievienoju reversÄs cilpas rakstÄ«Å”anas cilpu āC++ stilaā cienÄ«tÄjiem.
kods:
public class Bench
{
private List<int> _list;
private int[] _array;
[Params(100000, 10000000)] public int N;
[GlobalSetup]
public void Setup()
{
const int MIN = 1;
const int MAX = 10;
Random random = new Random();
_list = Enumerable.Repeat(0, N).Select(i => random.Next(MIN, MAX)).ToList();
_array = _list.ToArray();
}
[Benchmark]
public int ForList()
{
int total = 0;
for (int i = 0; i < _list.Count; i++)
{
total += _list[i];
}
return total;
}
[Benchmark]
public int ForListFromEnd()
{
int total = 0;t
for (int i = _list.Count-1; i > 0; i--)
{
total += _list[i];
}
return total;
}
[Benchmark]
public int ForeachList()
{
int total = 0;
foreach (int i in _list)
{
total += i;
}
return total;
}
[Benchmark]
public int ForeachArray()
{
int total = 0;
foreach (int i in _array)
{
total += i;
}
return total;
}
[Benchmark]
public int ForArray()
{
int total = 0;
for (int i = 0; i < _array.Length; i++)
{
total += _array[i];
}
return total;
}
[Benchmark]
public int ForArrayFromEnd()
{
int total = 0;
for (int i = _array.Length-1; i > 0; i--)
{
total += _array[i];
}
return total;
}
}
NET Core 2.2 un 3.0 veiktspÄjas Ätrums ir gandrÄ«z identisks. LÅ«k, ko es varÄju iegÅ«t .NET Core 3.0:
Varam secinÄt, ka masÄ«vu kolekcijas iteratÄ«vÄ apstrÄde ir ÄtrÄka, pateicoties tÄs iekÅ”Äjai optimizÄcijai un skaidrai kolekcijas lieluma pieŔķirÅ”anai. Ir arÄ« vÄrts atcerÄties, ka List kolekcijai ir savas priekÅ”rocÄ«bas, un jums vajadzÄtu izmantot pareizo kolekciju atkarÄ«bÄ no nepiecieÅ”amajiem aprÄÄ·iniem. Pat ja rakstÄt loÄ£iku darbam ar cilpÄm, neaizmirstiet, ka Ŕī ir parasta cilpa, un tÄ ir pakļauta arÄ« iespÄjamai cilpas optimizÄcijai. Pirms diezgan ilga laika habr tika publicÄts raksts: https://habr.com/ru/post/124910/. TÄ joprojÄm ir aktuÄla un ieteicama lasÄmviela.
Mest
Pirms gada es strÄdÄju uzÅÄmumÄ pie mantota projekta, un Å”ajÄ projektÄ bija normÄli apstrÄdÄt lauka validÄciju, izmantojot konstrukciju āmÄÄ£ini noÄ·ert un mestā. Jau tad sapratu, ka tÄ ir neveselÄ«ga biznesa loÄ£ika projektam, tÄpÄc, kad vien iespÄjams, centos Å”Ädu dizainu neizmantot. Bet izdomÄsim, kÄpÄc pieeja kļūdu novÄrÅ”anai ar Å”Ädu konstrukciju ir slikta. Es uzrakstÄ«ju nelielu kodu, lai salÄ«dzinÄtu abas pieejas, un katrai opcijai izveidoju etalonus.
kods:
public bool ContainsHash()
{
bool result = false;
foreach (var file in _files)
{
var extension = Path.GetExtension(file);
if (_hash.Contains(extension))
result = true;
}
return result;
}
public bool ContainsHashTryCatch()
{
bool result = false;
try
{
foreach (var file in _files)
{
var extension = Path.GetExtension(file);
if (_hash.Contains(extension))
result = true;
}
if(!result)
throw new Exception("false");
}
catch (Exception e)
{
result = false;
}
return result;
}
RezultÄtiem .NET Core 3.0 un Core 2.2 ir lÄ«dzÄ«gs rezultÄts (.NET Core 3.0):
IzmÄÄ£inÄÅ”anas nozveja padara kodu grÅ«tÄk saprotamu un palielina programmas izpildes laiku. Bet, ja jums ir nepiecieÅ”ama Ŕī konstrukcija, nevajadzÄtu ievietot tÄs koda rindas, kurÄs nav paredzÄts rÄ«koties ar kļūdÄm - tas padarÄ«s kodu vieglÄk saprotamu. Faktiski sistÄmu noslogo ne tik daudz izÅÄmumu apstrÄde, bet gan paÅ”u kļūdu izmeÅ”ana, izmantojot jauno izÅÄmuma konstrukciju.
IzÅÄmumu izmeÅ”ana notiek lÄnÄk nekÄ dažas klases, kas savÄks kļūdu vajadzÄ«gajÄ formÄtÄ. Ja apstrÄdÄjat veidlapu vai dažus datus un skaidri zinÄt, kÄdai jÄbÅ«t kļūdai, kÄpÄc gan to neapstrÄdÄt?
NevajadzÄtu rakstÄ«t jaunu Exception() konstrukciju, ja Ŕī situÄcija nav ÄrkÄrtÄja. IzÅÄmuma apstrÄde un meÅ”ana ir ļoti dÄrga!!!
Savas 5 gadu pieredzes laikÄ, strÄdÄjot pie .NET platformas, esmu saskÄries ar daudziem projektiem, kuros tika izmantota virkÅu saskaÅoÅ”ana. Es redzÄju arÄ« Å”Ädu attÄlu: bija viens Enterprise risinÄjums ar daudziem projektiem, no kuriem katrs veica virkÅu salÄ«dzinÄÅ”anu atŔķirÄ«gi. Bet kas bÅ«tu jÄizmanto un kÄ to unificÄt? Rihtera grÄmatÄ CLR caur C# es izlasÄ«ju informÄciju, ka metode ToUpperInvariant() ir ÄtrÄka par ToLowerInvariant().
Fragments no grÄmatas:
Protams, es tam neticÄju un nolÄmu veikt dažus testus .NET Framework, un rezultÄts mani Å”okÄja ā veiktspÄjas pieaugums ir vairÄk nekÄ 15%. PÄc tam, ierodoties darbÄ nÄkamajÄ rÄ«tÄ, es parÄdÄ«ju Å”os mÄrÄ«jumus saviem priekÅ”niekiem un devu viÅiem piekļuvi pirmkodam. PÄc tam 2 no 14 projektiem tika mainÄ«ti, lai pielÄgotos jaunajiem mÄrÄ«jumiem, un, Åemot vÄrÄ, ka Å”ie divi projekti pastÄvÄja, lai apstrÄdÄtu milzÄ«gas Excel tabulas, rezultÄts produktam bija vairÄk nekÄ nozÄ«mÄ«gs.
PiedÄvÄju arÄ« mÄrÄ«jumus dažÄdÄm .NET Core versijÄm, lai katrs varÄtu izdarÄ«t izvÄli par optimÄlÄko risinÄjumu. Un es tikai vÄlos piebilst, ka uzÅÄmumÄ, kurÄ es strÄdÄju, mÄs izmantojam ToUpper(), lai salÄ«dzinÄtu virknes.
kods:
public const string defaultString = "VXTDuob5YhummuDq1PPXOHE4PbrRjYfBjcHdFs8UcKSAHOCGievbUItWhU3ovCmRALgdZUG1CB0sQ4iMj8Z1ZfkML2owvfkOKxBCoFUAN4VLd4I8ietmlsS5PtdQEn6zEgy1uCVZXiXuubd0xM5ONVZBqDu6nOVq1GQloEjeRN8jXrj0MVUexB9aIECs7caKGddpuut3";
[Benchmark]
public bool ToLower()
{
return defaultString.ToLower() == defaultString.ToLower();
}
[Benchmark]
public bool ToLowerInvariant()
{
return defaultString.ToLowerInvariant() == defaultString.ToLowerInvariant();
}
[Benchmark]
public bool ToUpper()
{
return defaultString.ToUpper() == defaultString.ToUpper();
}
[Benchmark]
public bool ToUpperInvariant()
{
return defaultString.ToUpperInvariant() == defaultString.ToUpperInvariant();
}
ProgrammÄ .NET Core 3.0 katras no Ŕīm metodÄm pieaugums ir ~x2 un lÄ«dzsvaro implementÄcijas savÄ starpÄ.
LÄ«meÅa kompilÄcija
SavÄ pÄdÄjÄ rakstÄ es Ä«si aprakstÄ«ju Å”o funkcionalitÄti, es vÄlÄtos labot un papildinÄt savus vÄrdus. VairÄku lÄ«meÅu kompilÄcija paÄtrina jÅ«su risinÄjuma palaiÅ”anas laiku, taÄu jÅ«s upurÄjat to, ka jÅ«su koda daļas fonÄ tiks kompilÄtas optimizÄtÄkÄ versijÄ, kas var radÄ«t nelielu papildu izdevumu. LÄ«dz ar NET Core 3.0 parÄdÄ«Å”anos ir samazinÄjies izveides laiks projektiem ar iespÄjotu lÄ«meÅu kompilÄciju, un ir novÄrstas ar Å”o tehnoloÄ£iju saistÄ«tÄs kļūdas. IepriekÅ” Ŕī tehnoloÄ£ija izraisÄ«ja kļūdas pirmajos ASP.NET Core pieprasÄ«jumos un sasalst pirmÄs versijas laikÄ daudzlÄ«meÅu kompilÄcijas režīmÄ. PaÅ”laik tas ir iespÄjots pÄc noklusÄjuma .NET Core 3.0, taÄu varat to atspÄjot, ja vÄlaties. Ja esi komandas vadÄ«tÄja, vecÄkais, vidÄjais vai nodaļas vadÄ«tÄjs, tad jÄsaprot, ka strauja projektu attÄ«stÄ«ba palielina komandas vÄrtÄ«bu un Ŕī tehnoloÄ£ija ļaus ietaupÄ«t laiku abiem izstrÄdÄtÄjiem. un paÅ”a projekta laiks.
.NET līmenis uz augŔu
Jauniniet savu .NET Framework/.NET Core versiju. Bieži vien katra jaunÄ versija nodroÅ”ina papildu veiktspÄjas pieaugumu un pievieno jaunas funkcijas.
Bet kÄdi tieÅ”i ir ieguvumi? ApskatÄ«sim dažus no tiem:
.NET Core 3.0 ieviesa R2R attÄlus, kas samazinÄs .NET Core lietojumprogrammu startÄÅ”anas laiku.
Ar versiju 2.2 parÄdÄ«jÄs Tier Compilation, pateicoties kurai programmÄtÄji pavadÄ«s mazÄk laika, uzsÄkot projektu.
Atbalsts jauniem .NET standartiem.
Atbalsts jaunai programmÄÅ”anas valodas versijai.
OptimizÄcija, ar katru jauno versiju tiek uzlabota bÄzes bibliotÄku kolekcija/StruktÅ«ra/Stream/String/Regex optimizÄcija un daudz kas cits. Ja migrÄjat no .NET Framework uz .NET Core, jÅ«s iegÅ«sit lielu veiktspÄjas uzlabojumu. KÄ piemÄru es pievienoju saiti uz dažÄm optimizÄcijÄm, kas tika pievienotas .NET Core 3.0: https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/
SecinÄjums
Rakstot kodu, ir vÄrts pievÄrst uzmanÄ«bu dažÄdiem sava projekta aspektiem un izmantot savas programmÄÅ”anas valodas un platformas iespÄjas, lai sasniegtu labÄko rezultÄtu. PriecÄÅ”os, ja padalÄ«tos ar savÄm zinÄÅ”anÄm par optimizÄciju .NET.