Inqaku elingaphumelelanga malunga nokukhawulezisa ukucamngca

Ndiza kuchaza ngokukhawuleza isihloko senqaku. Isicwangciso sokuqala yayikukunika iingcebiso ezilungileyo, ezithembekileyo malunga nendlela yokukhawulezisa ukusetyenziswa kokucamngca usebenzisa umzekelo olula kodwa oyinyaniso, kodwa ngexesha lokulinganisa kwavela ukuba ukucamngca akucothi njengoko ndandicinga, i-LINQ icotha kunamaphupha am amabi. Kodwa ekugqibeleni kwavela ukuba nam ndenze impazamo kwimilinganiselo ... Iinkcukacha zeli bali lobomi ziphantsi kwe-cut and in the comments. Kuba umzekelo uqhelekile kwaye uphunyezwe ngokomgaqo njengoko uqhele ukwenziwa kwishishini, kuye kwaba yinto enomdla, njengoko kubonakala kum, umboniso wobomi: ifuthe kwisantya somxholo ophambili wenqaku. ayibonakali ngenxa yengqiqo yangaphandle: i-Moq, i-Autofac, i-EF Core kunye nezinye "iibhendi".

Ndaqala ukusebenza phantsi kwempembelelo yeli nqaku: Kutheni iReflection icotha

Njengoko ubona, umbhali ucebisa ukusebenzisa abathunywa abahlanganisiweyo endaweni yokubiza ngokuthe ngqo iindlela zohlobo lokubonisa njengendlela enkulu yokukhawulezisa isicelo. Kukho, ngokuqinisekileyo, ukukhutshwa kwe-IL, kodwa ndingathanda ukuyiphepha, kuba le yeyona ndlela inzima kakhulu yokwenza umsebenzi, ogcwele iimpazamo.

Ukuqwalasela ukuba ndihlala ndibamba uluvo olufanayo malunga nesantya sokucinga, andizange ndijonge ngokukodwa ukubuza izigqibo zombhali.

Ndihlala ndidibana nokusetyenziswa ngokungenangqondo kokubonakalisa kwishishini. Uhlobo luthathiwe. Ulwazi malunga nepropati luthathiwe. Indlela ye-SetValue ibizwa kwaye wonke umntu uyavuya. Ixabiso lifikile kwindawo ekujoliswe kuyo, wonke umntu uyavuya. Abantu abakrelekrele kakhulu - abantu abadala kunye nabakhokelayo beqela - babhala izandiso zabo zokuchasa, ngokusekwe kuphunyezo olungenangqondo olunjalo "lomhlaba wonke" weemephu zolunye uhlobo ukuya kolunye. Undoqo uqhelekile oku: sithatha yonke imihlaba, sithathe zonke iipropati, siphindaphinde phezu kwazo: ukuba amagama ohlobo lwamalungu ahambelana, siphumeza i-SetValue. Ngamaxesha ngamaxesha sibamba ngaphandle ngenxa yeempazamo apho asizange sifumane ipropati kwenye yeentlobo, kodwa nalapha kukho indlela yokuphuma ephucula ukusebenza. Zama/bamba.

Ndibone abantu bephinda baqulunqa iipars kunye neemephu ngaphandle kokuba baxhobe ngokupheleleyo ngolwazi malunga nendlela oomatshini abafike phambi kwabo basebenza ngayo. Ndibone abantu befihla ukuphunyezwa kwabo okungenangqondo ngasemva kwezicwangciso, ngasemva konxibelelwano, emva kweenaliti, ngokungathi oku kuya kuxolela i-bacchanalia elandelayo. Ndiye ndanyusa impumlo yam xa ndikubona oko. Ngapha koko, andizange ndilinganise ukuvuza kokwenyani kokusebenza, kwaye, ukuba kuyenzeka, nditshintshe nje ukuphunyezwa kolona β€œlona lufanelekileyo” ngakumbi ukuba ndingafumana izandla zam kuyo. Ke ngoko, imilinganiselo yokuqala exoxwe ngezantsi yandibhida kakhulu.

Ndicinga ukuba abaninzi benu, befunda i-Richter okanye ezinye i-ideologists, baye bafumana inkcazo efanelekileyo ngokupheleleyo yokuba ukubonakalisa ikhowudi yinto enempembelelo embi kakhulu ekusebenzeni kwesicelo.

Ukufowuna ukubonakaliswa kunyanzela i-CLR ukuba ihambe kwiindibano ukuze ifumane leyo bayifunayo, ikhuphe imetadata yabo, icazulule, njl. Ukongeza, ukucamngca ngelixa udlula ulandelelwano kukhokelela ekwabiweni kwememori eninzi. Sisebenzisa imemori, i-CLR ityhila i-GC kwaye iifriezes ziqala. Ifanele ukucotha ngokuphawulekayo, ndikholelwe. Izixa ezikhulu zeememori kwiiseva zemveliso zanamhlanje okanye oomatshini bamafu abathinteli ukulibaziseka okuphezulu. Ngapha koko, kokukhona inkumbulo ingaphezulu, kokukhona kunokwenzeka ukuba UKWAZI ukuba isebenza njani i-GC. Ukucamngca, ngokwethiyori, iragi ebomvu eyongezelelweyo kuye.

Nangona kunjalo, sonke sisebenzisa izikhongozeli ze-IoC kunye neemephu zemihla, umgaqo wokusebenza nawo usekwe kwimbonakalo, kodwa akukho mibuzo malunga nokusebenza kwabo. Hayi, hayi ngenxa yokuba ukwaziswa kokuxhomekeka kunye nokutsalwa kwiimodeli zangaphandle ezilinganiselweyo ziyimfuneko kangangokuba kufuneka sincame ukusebenza kuyo nayiphi na imeko. Yonke into ilula - ayichaphazeli kakhulu ukusebenza.

Inyani yeyokuba ezona zicwangciso-nkqubo zixhaphakileyo ezisekelwe kwitekhnoloji yokubonisa zisebenzisa zonke iintlobo zamaqhinga ukuze zisebenze nayo ngokufanelekileyo. Ngokuqhelekileyo le yi-cache. Ngokuqhelekileyo la ngamabinzana amagama kunye nabathunywa abahlanganiswe kumthi wokubonisa. I-automapper efanayo igcina isichazi-magama esikhuphisanayo esihambelana neentlobo ezinemisebenzi enokuguqula enye ibe kwenye ngaphandle kokufowuna ukubonakaliswa.

Kufezwa njani oku? Ngokusisiseko, oku akwahlukanga kwingqiqo esetyenziswa liqonga ngokwalo ukuvelisa ikhowudi yeJIT. Xa indlela ibizwa okokuqala, iyaqulunqwa (kwaye, ewe, le nkqubo ayikhawulezi); kwiifowuni ezilandelayo, ulawulo lukhutshelwa kwindlela esele iqulunqiwe, kwaye akuyi kubakho kutsalwa kwentsebenzo ebalulekileyo.

Kwimeko yethu, ungasebenzisa ukuhlanganiswa kwe-JIT kwaye emva koko usebenzise ukuziphatha okuhlanganisiweyo kunye nokusebenza okufanayo njengabalingani bayo be-AOT. Iintetho ziya kusinceda kule meko.

Umgaqo ekuthethwa ngawo unokuqulunqwa ngokufutshane ngolu hlobo lulandelayo:
Kufuneka ugcine isiphumo sokugqibela sokubonisa njengomthunywa oqulethe umsebenzi oqokelelweyo. Kwakhona kunengqiqo ukugcina zonke izinto eziyimfuneko kunye nolwazi lohlobo kwiinkalo zohlobo lwakho, umsebenzi, ezigcinwe ngaphandle kwezinto.

Kukho ingqiqo kule nto. Ingqiqo isixelela ukuba ukuba into inokudityaniswa ize igcinwe, kufuneka yenziwe.

Ukujonga phambili, kufuneka kuthiwe i-cache ekusebenzeni kunye ne-reflection ineenzuzo zayo, nokuba awusebenzisi indlela ecetywayo yokuqulunqa iintetho. Ngokwenyani, apha ndiphinda ndiphinda ezi nkcazo zombhali wenqaku endibhekisa kulo ngasentla.

Ngoku malunga nekhowudi. Makhe sijonge umzekelo osekelwe kwiintlungu zam zamva nje ekufuneka ndijamelane nazo kwimveliso enzima yeziko letyala. Onke amaqumrhu abubuxoki ukuze kungabikho mntu unokuthelekelela.

Kukho undoqo. Makubekho uQhagamshelwano. Kukho iileta ezinomzimba osemgangathweni, apho i-parser kunye ne-hydrator yenza abafowunelwa abafanayo. Yafika ileta, sayifunda, sayicazulula kwi-key-value pairs, sakha umfownelwa, sayigcina kwi-database.

Yeyokuqala. Masithi umfowunelwa uneempawu ezipheleleyo Igama, Ubudala kunye neFowuni yoQhagamshelwano. Le datha idluliswa kwileta. Ishishini likwafuna inkxaso ukuze likwazi ukongeza ngokukhawuleza izitshixo ezitsha zokubonisa iipropati zequmrhu zibe ngababini kumzimba weleta. Kwimeko apho umntu enze i-typo kwi-template okanye ukuba ngaphambi kokukhululwa kuyimfuneko ukuqalisa ngokukhawuleza imephu evela kwiqabane elitsha, ukuziqhelanisa nefomathi entsha. Emva koko singongeza ulungelelwaniso olutsha lwemephu njengedatha engabizi kakhulu. Oko kukuthi, umzekelo wobomi.

Siphumeza, senze iimvavanyo. Iyasebenza.

Andiyi kubonelela ngekhowudi: kukho imithombo emininzi, kwaye iyafumaneka kwiGitHub ngekhonkco ekupheleni kwenqaku. Ungazilayisha, uzithuthumbise ngaphaya kokuqondwa kwaye uzilinganise, njengoko kuya kuchaphazela kwimeko yakho. Ndiza kunika kuphela ikhowudi yeendlela ezimbini zetemplate ezahlula i-hydrator, eyayifanele ukuba ikhawuleze, ukusuka kwi-hydrator, eyayifanele ukuba icotha.

Ingqiqo yile ilandelayo: indlela yetemplate ifumana izibini eziveliswe yi-basic parser logic. Uluhlu lwe-LINQ luluhlu kunye nengqiqo esisiseko ye-hydrator, eyenza isicelo kumxholo wesiseko sedatha kwaye ithelekise izitshixo kunye nababini ukusuka kwi-parser (kule misebenzi kukho ikhowudi ngaphandle kwe-LINQ yokuthelekisa). Emva koko, izibini zigqithiselwa kwindlela ephambili ye-hydration kwaye amaxabiso ezibini amiselwe kwiipropati ezihambelanayo zequmrhu.

β€œFast” (Isimaphambili esiFast in the benchmarks):

 protected override Contact GetContact(PropertyToValueCorrelation[] correlations)
        {
            var contact = new Contact();
            foreach (var setterMapItem in _proprtySettersMap)
            {
                var correlation = correlations.FirstOrDefault(x => x.PropertyName == setterMapItem.Key);
                setterMapItem.Value(contact, correlation?.Value);
            }
            return contact;
        }

Njengoko sinokubona, ingqokelela engatshintshiyo eneempawu zesetter isetyenzisiwe-i-lambdas ehlanganisiweyo ebiza iqumrhu le-setter. Yenziwe ngale khowudi ilandelayo:

        static FastContactHydrator()
        {
            var type = typeof(Contact);
            foreach (var property in type.GetProperties())
            {
                _proprtySettersMap[property.Name] = GetSetterAction(property);
            }
        }

        private static Action<Contact, string> GetSetterAction(PropertyInfo property)
        {
            var setterInfo = property.GetSetMethod();
            var paramValueOriginal = Expression.Parameter(property.PropertyType, "value");
            var paramEntity = Expression.Parameter(typeof(Contact), "entity");
            var setterExp = Expression.Call(paramEntity, setterInfo, paramValueOriginal).Reduce();
            
            var lambda = (Expression<Action<Contact, string>>)Expression.Lambda(setterExp, paramEntity, paramValueOriginal);

            return lambda.Compile();
        }

Ngokubanzi kucacile. Sinqumla kwiipropathi, sidale abathunywa kwabo bafowunela iisethi, kwaye sibagcine. Emva koko siye sitsale umnxeba xa kuyimfuneko.

β€œScotha” (Isimaphambili esicothayo kwibenchmarks):

        protected override Contact GetContact(PropertyToValueCorrelation[] correlations)
        {
            var contact = new Contact();
            foreach (var property in _properties)
            {
                var correlation = correlations.FirstOrDefault(x => x.PropertyName == property.Name);
                if (correlation?.Value == null)
                    continue;

                property.SetValue(contact, correlation.Value);
            }
            return contact;
        }

Apha sidlula ngokukhawuleza iipropathi kwaye sifowunele i-SetValue ngokuthe ngqo.

Ukucaca kunye nereferensi, ndiphumeze indlela engenangqondo ebhala amaxabiso ezibini zolungelelwaniso lwazo ngqo kumacandelo equmrhu. Isimaphambili-Manuwali.

Ngoku makhe sithathe iBenchmarkDotNet kwaye sijonge ukusebenza. Kwaye ngokukhawuleza ... (spoiler - oku akusiyo umphumo ochanekileyo, iinkcukacha zingezantsi)

Inqaku elingaphumelelanga malunga nokukhawulezisa ukucamngca

Sibona ntoni apha? Iindlela ezithwala ngoloyiso isimaphambili esikhawulezayo zijika zicotha phantse kuzo zonke iipasi kuneendlela ezinesiqalo esicothayo. Oku kuyinyaniso kuzo zombini ulwabiwo kunye nesantya somsebenzi. Kwelinye icala, ukuphunyezwa okuhle kunye nokuncomekayo kwemephu usebenzisa iindlela ze-LINQ ezenzelwe oku naphi na apho kunokwenzeka, ngokuchaseneyo, kunciphisa kakhulu imveliso. Umahluko ngowocwangco. Intsingiselo ayitshintshi ngamanani ahlukeneyo okupasa. Umahluko kuphela kwisikali. Nge-LINQ yi-4 - 200 amaxesha acothayo, kukho inkunkuma eninzi malunga nesikali esifanayo.

OLUHLAZIYIWEYO

Andizange ndiwakholelwe amehlo am, kodwa okona kubaluleke ngakumbi, ugxa wethu akazange awakholelwe amehlo am okanye ikhowudi yam - NguDmitry Tikhonov 0x1000000. Ukusijonga kabini isisombululo sam, wafumanisa ngobuchule kwaye wachaza impazamo endiyiphosileyo ngenxa yotshintsho oluninzi ekuphunyezweni, okokuqala ukuya kokugqibela. Emva kokulungisa i-bug ekusetweni kwe-Moq, zonke iziphumo zawela endaweni. Ngokweziphumo zokuvavanya kwakhona, eyona nto iphambili ayitshintshi - i-LINQ isachaphazela ukusebenza ngakumbi kunokubonakalisa. Nangona kunjalo, kuhle ukuba umsebenzi kunye nokuhlanganiswa kwe-Expression awenziwanga ilize, kwaye umphumo ubonakala ngokubini kulwabiwo kunye nexesha lokuphumeza. Ukuqaliswa kokuqala, xa imimandla engatshintshiyo iqaliswa, iyacotha ngokwemvelo kwindlela "ekhawulezayo", kodwa ke imeko iyatshintsha.

Nasi isiphumo sovavanyo kwakhona:

Inqaku elingaphumelelanga malunga nokukhawulezisa ukucamngca

Isiphelo: xa usebenzisa ukubonakaliswa kwishishini, akukho mfuneko ithile yokubhenela kumaqhinga - i-LINQ iya kudla imveliso ngakumbi. Nangona kunjalo, kwiindlela zomthwalo ophezulu ezifuna ukulungiswa, unokugcina imbonakalo ngendlela yabaqalisi kunye nabaqulunqi abathunyiweyo, abaya kuthi emva koko babonelele ngengqiqo "ekhawulezayo". Ngale ndlela unokugcina zombini ukuguquguquka kokubonakalisa kunye nesantya sesicelo.

Ikhowudi yebenchmark iyafumaneka apha. Nabani na unokuwajonga kabini amazwi am:
Iimvavanyo zeHabraReflection

I-PS: ikhowudi kwiimvavanyo isebenzisa i-IoC, kwaye kwiibenchmarks isebenzisa ulwakhiwo olucacileyo. Inyaniso kukuba ekuphunyezweni kokugqibela ndinqumle zonke izinto ezinokuchaphazela ukusebenza kwaye zenze umphumo ube nomsindo.

PPS: Enkosi kumsebenzisi NguDmitry Tikhonov @0x1000000 ukufumanisa impazamo yam yokuseta iMoq, echaphazele imilinganiselo yokuqala. Ukuba omnye wabafundi unekarma eyaneleyo, nceda uyithande. Yama indoda, yafunda le ndoda, yajonga kabini yaza yabonisa impazamo. Ndicinga ukuba oku kuyifanele intlonipho novelwano.

I-PPPS: enkosi kumfundi onenyameko ofikelele ezantsi kwesitayile kunye noyilo. Ndimele ukufana kunye nokulula. Idiplomacy yenkcazo-ntetho ishiya into enqwenelekayo, kodwa ndikuthathele ingqalelo ukugxekwa. Ndicela iprojectile.

umthombo: www.habr.com

Yongeza izimvo