Lahatsoratra tsy nahomby momba ny fisaintsainana haingana

Hazavaiko avy hatrany ny lohatenin'ilay lahatsoratra. Ny drafitra tany am-boalohany dia ny hanome torohevitra tsara sy azo ianteherana amin'ny fanafainganana ny fampiasana ny fisaintsainana amin'ny fampiasana ohatra tsotra nefa tena misy, saingy nandritra ny benchmarking dia hita fa tsy miadana araka ny noheveriko ny fisaintsainana, miadana kokoa ny LINQ noho ny amin'ny nofy ratsy. Saingy tamin'ny farany dia hita fa nanao fahadisoana ihany koa aho tamin'ny fandrefesana ... Ny antsipiriany momba ity tantaram-piainana ity dia eo ambanin'ny fanapahana sy ao amin'ny fanehoan-kevitra. Satria ny ohatra dia mahazatra ary ampiharina amin'ny fitsipika toy ny mahazatra amin'ny orinasa iray, dia hita fa tena mahaliana, araka ny fahitako azy, ny fanehoana ny fiainana: ny fiantraikany amin'ny hafainganam-pandehan'ny lohahevitra fototra amin'ny lahatsoratra dia tsy tsikaritra noho ny lojika ivelany: Moq, Autofac, EF Core sy ny hafa "bands".

Nanomboka niasa teo ambanin'ny fahatsapana an'ity lahatsoratra ity aho: Nahoana no miadana ny Reflection

Araka ny hitanao, ny mpanoratra dia manoro hevitra ny hampiasa solontena voaangona fa tsy hiantso mivantana ny fomba karazana fisaintsainana ho fomba tsara hanafainganana ny fampiharana. Misy, mazava ho azy, ny famoahana ny IL, saingy tiako ny misoroka izany, satria io no fomba fiasa be mpampiasa indrindra amin'ny fanatanterahana ny asa, izay feno lesoka.

Raha jerena fa nitazona hevitra mitovy foana momba ny hafainganan'ny fisaintsainana aho, dia tsy nieritreritra manokana ny hanontany ny fehin-kevitry ny mpanoratra aho.

Matetika aho no mahita ny fampiasana tsy misy dikany amin'ny orinasa. Ny karazana dia raisina. Ny fampahalalana momba ny fananana dia raisina. Ny fomba SetValue dia antsoina ary faly ny rehetra. Tonga teny amin’ny saha kendrena ny sanda, faly ny rehetra. Olona tena marani-tsaina - zokiolona sy mpitarika ny ekipa - manoratra ny fanitarana azy ireo mba hanohitra, mifototra amin'ny fampiharana tsy misy dikany toy izany "universal" sarintany amin'ny karazana iray mankany amin'ny iray hafa. Ny tena zava-dehibe dia matetika izao: maka ny saha rehetra isika, maka ny fananana rehetra, mamerina azy ireo: raha mifanandrify ny anaran'ireo karazana mpikambana dia manatanteraka ny SetValue. Indraindray isika dia mahazo maningana noho ny hadisoana izay tsy nahitana fananana tao amin'ny iray amin'ireo karazany, fa na dia eto aza dia misy fomba hivoahana izay manatsara ny fampisehoana. Andramo/sambory.

Nahita olona nanamboatra parser sy mpanao sari-tany aho nefa tsy mirongo fitaovam-piadiana feno momba ny fomba fiasan'ireo milina teo alohany. Nahita olona aho nanafina ny fampiharana tsy misy dikany ao ambadiky ny paikady, ao ambadiky ny interface, ao ambadiky ny tsindrona, toy ny hoe manala tsiny ny bacchanalia manaraka izany. Nitodika aho tamin'ny fahatsapana toy izany. Raha ny marina dia tsy norefesiko ny fivoahana tena izy, ary, raha azo atao, dia nanova tsotra izao ny fampiharana ho "tsara indrindra" aho raha afaka mahazo ny tanako. Noho izany, ny fandrefesana voalohany resahina etsy ambany dia nanakorontana ahy.

Heveriko fa maro aminareo, mamaky an'i Richter na ireo ideolojia hafa, no nahita fanambarana ara-drariny tanteraka fa ny fisaintsainana amin'ny fehezan-dalΓ na dia tranga iray izay misy fiantraikany ratsy be amin'ny fanatanterahana ny fampiharana.

Ny fiantsoana fisaintsainana dia manery ny CLR handeha amin'ny fivoriambe mba hahitana izay ilainy, haka ny metadatany, hamakiana azy ireo, sns. Fanampin'izany, ny fisaintsainana eo am-pamakivakiana ny filaharana dia mitarika amin'ny fizarana fahatsiarovana be dia be. Mampiasa fitadidiana izahay, ny CLR dia mamoaka ny GC ary manomboka ny friezes. Tokony ho miadana be izany, minoa ahy. Ny fitadidiana be dia be amin'ny lohamilina famokarana maoderina na milina rahona dia tsy manakana ny fahataran'ny fanodinana. Raha ny marina, arakaraky ny fitadidiana no hahamarika kokoa ny fomba fiasan'ny GC. Ny fisaintsainana, raha ny teoria, dia lamba mena fanampiny ho azy.

Na izany aza, isika rehetra dia mampiasa ny kaontenera IoC sy ny sarintany daty, ny fitsipiky ny fiasa izay mifototra amin'ny fisaintsainana ihany koa, saingy matetika tsy misy fanontaniana momba ny zava-bitany. Tsia, tsy noho ny fampidirana ny fiankinan-doha sy ny fanesorana avy amin'ny modely konteksta voafetra ivelany dia tena ilaina ka tsy maintsy manao sorona ny zava-bita na inona na inona. Tsotra kokoa ny zava-drehetra - tena tsy misy fiantraikany amin'ny fampisehoana izany.

Ny zava-misy dia ny rafitra mahazatra indrindra mifototra amin'ny teknolojia fisaintsainana dia mampiasa karazana fika rehetra mba hiasa tsara kokoa amin'izany. Matetika izany dia cache. Matetika ireo dia Expressions sy solontena natambatra avy amin'ny hazo fitenenana. Io automatique io ihany no mitazona rakibolana mifaninana izay mifanandrify amin'ireo karazana fiasa izay afaka mifamadika amin'ny iray hafa nefa tsy miantso fisaintsainana.

Ahoana no ahatratrarana izany? Amin'ny ankapobeny, tsy misy hafa amin'ny lojika izay ampiasain'ny sehatra manokana hamokarana kaody JIT izany. Rehefa antsoina voalohany ny fomba iray dia atambatra (ary, eny, tsy haingana ity dingana ity); amin'ny antso manaraka, ny fanaraha-maso dia afindra amin'ny fomba efa natambatra, ary tsy hisy fisintonana zava-bita lehibe.

Amin'ity tranga ity, azonao atao koa ny mampiasa JIT compilation ary avy eo mampiasa ny fitondran-tena natambatra miaraka amin'ny fampisehoana mitovy amin'ny AOT mitovy aminy. Ny fanehoan-kevitra dia hanampy antsika amin'ity tranga ity.

Ny fitsipika resahina dia azo fehezina fohy toy izao manaraka izao:
Tokony hotehirizinao ny vokatra farany amin'ny fisaintsainana ho solontena misy ny asa natambatra. Misy dikany ihany koa ny mitahiry ireo zavatra ilaina rehetra miaraka amin'ny fampahalalana karazana ao amin'ny sahan'ny karazana anao, ny mpiasa, izay voatahiry ivelan'ny zavatra.

Misy lojika izany. Ny saina mahazatra dia milaza amintsika fa raha misy zavatra azo atambatra sy voatahiry dia tokony hatao izany.

Raha jerena aloha dia tokony ho lazaina fa manana tombony ny cache amin'ny fiasana amin'ny fisaintsainana, na dia tsy mampiasa ny fomba fanangonam-pitenenana aza ianao. Raha ny marina, eto dia averiko fotsiny ireo teny nosoratan'ny mpanoratra ny lahatsoratra izay resahiko etsy ambony.

Izao momba ny kaody. Andeha hojerentsika ny ohatra iray izay mifototra amin'ny fanaintainako vao haingana izay tsy maintsy natrehiko tamin'ny famokarana matotra amin'ny andrim-bola lehibe iray. Ny enti-mody rehetra dia foronina mba tsy hisy haminavina.

Misy essence. Aoka hisy Contact. Misy litera manana vatana manara-penitra, izay namoronan'ny parser sy ny hydrator ireo fifandraisana ireo. Nisy taratasy tonga, novakianay, nozarainay ho tsiroaroa manan-danja, namorona fifandraisana, ary notehirizina tao amin'ny tahiry.

Elementary io. Andeha hatao hoe manana ny fananana Anarana feno, taona ary telefaonina mifandray ny fifandraisana. Ampitaina amin'ny taratasy izany data izany. Ny fandraharahana koa dia maniry ny fanohanana afaka manampy haingana ireo fanalahidy vaovao amin'ny fametahana ny fananan'ny orinasa ho tsiroaroa ao amin'ny vatan'ny taratasy. Raha sanatria misy manao typo amin'ny mΓ΄dely na raha alohan'ny famoahana dia ilaina ny manomboka maika ny sarintany avy amin'ny mpiara-miasa vaovao, mampifanaraka amin'ny endrika vaovao. Avy eo isika dia afaka manampy fifandraisana sarintany vaovao ho toy ny datafix mora. Izany hoe ohatra amin’ny fiainana.

Manatanteraka isika, mamorona fitsapana. Asa.

Tsy hanome ny code aho: be dia be ny loharano, ary hita ao amin'ny GitHub amin'ny alΓ lan'ny rohy amin'ny faran'ny lahatsoratra. Azonao atao ny mameno azy ireo, mampijaly azy ireo tsy ekena ary mandrefy azy ireo, araka izay mety hisy fiantraikany amin'ny raharahanao. Ny kaody amin'ny fomba mΓ΄dely roa ihany no homeko izay manavaka ny hydrator, izay tokony ho haingana, amin'ny hydrator, izay tokony ho miadana.

Ny lojika dia toy izao manaraka izao: ny fomba mΓ΄dely dia mandray tsiroaroa novokarin'ny lojika parser fototra. Ny sosona LINQ dia ny parser sy ny lojika fototra amin'ny hydrator, izay manao fangatahana amin'ny contexte database ary mampitaha ny lakile miaraka amin'ny mpivady avy amin'ny parser (ho an'ireo fiasa ireo dia misy code tsy misy LINQ ho fampitahana). Avy eo, ny mpivady dia ampitaina amin'ny fomba hydration lehibe ary ny sandan'ny mpivady dia apetraka amin'ny fananana mifanaraka amin'ilay orinasa.

β€œFast” (Tovona haingana amin'ny benchmark):

 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;
        }

Araka ny hitantsika dia ampiasaina ny fanangonana static miaraka amin'ny fananana setter - lambdas natambatra izay antsoina hoe entity setter. Noforonin'ny code manaraka:

        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();
        }

Amin'ny ankapobeny dia mazava izany. Mamakivaky ireo fananana izahay, mamorona solontena ho an'ireo izay miantso setter, ary mamonjy azy ireo. Dia miantso izahay rehefa ilaina.

"Miadana" (Tovona miadana amin'ny mari-pamantarana):

        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;
        }

Eto izahay dia mandalo avy hatrany ny fananana ary miantso mivantana ny SetValue.

Mba hanazavana sy ho fanondroana, dia nampihatra fomba tsy misy dikany aho izay manoratra ny soatoavin'ny mpivady fifandraisana mivantana amin'ny sahan'ny orinasa. Tovona - Manual.

Andeha isika haka BenchmarkDotNet ary handinika ny zava-bita. Ary tampoka ... (spoiler - tsy izany no valiny marina, ny antsipiriany dia etsy ambany)

Lahatsoratra tsy nahomby momba ny fisaintsainana haingana

Inona no hitantsika eto? Ireo fomba izay mitondra ny prefix Fast dia miadana kokoa amin'ny saika mandalo rehetra noho ny fomba miaraka amin'ny prefix Slow. Marina izany na amin'ny fizarana sy ny hafainganan'ny asa. Amin'ny lafiny iray, ny fampiharana kanto sy kanto amin'ny sarintany mampiasa fomba LINQ natao ho an'izany na aiza na aiza azo atao, ny mifanohitra amin'izany, dia mampihena be ny vokatra. Ny fahasamihafana dia ny filaminana. Tsy miova ny fironana amin'ny isa isan-karazany. Ny hany maha samy hafa dia eo amin'ny ambaratonga. Miaraka amin'ny LINQ dia miadana in-4 - 200 heny izany, betsaka kokoa ny fako amin'ny ambaratonga mitovy.

VAOVAO

Tsy nino ny masoko aho, fa ny tena zava-dehibe dia tsy nino ny masoko na ny code-ko ny mpiara-miasa aminay - Dmitry Tikhonov 0x1000000. Rehefa nojerena indroa ny vahaolana nataoko, dia nahita tsara izy ary nanondro ny hadisoana tsy hitako noho ny fiovana maromaro tamin'ny fampiharana, voalohany ka hatramin'ny farany. Rehefa avy nanamboatra ny bug hita tao amin'ny setup Moq dia tonga tany amin'ny toerany ny valiny rehetra. Araka ny valin'ny retest dia tsy miova ny fironana lehibe - ny LINQ dia mbola misy fiantraikany amin'ny fampisehoana mihoatra noho ny fisaintsainana. Na izany aza, mahafinaritra fa ny asa miaraka amin'ny Expression compilation dia tsy vita foana, ary ny vokatra dia hita ao amin'ny fizarana sy ny fotoana famonoana. Ny fandefasana voalohany, rehefa atomboka ny saha static, dia miadana kokoa ho an'ny fomba "haingana", saingy miova ny toe-javatra avy eo.

Ity ny vokatry ny retest:

Lahatsoratra tsy nahomby momba ny fisaintsainana haingana

Fehiny: rehefa mampiasa fisaintsainana amin'ny orinasa iray dia tsy ilaina ny mampiasa fika manokana - ny LINQ dia hihinana vokatra bebe kokoa. Na izany aza, amin'ny fomba avo lenta izay mitaky fanatsarana, azonao atao ny mitahiry fisaintsainana amin'ny endrika fanombohana sy mpanangona delegasiona, izay hanome lojika "haingana". Amin'izany fomba izany dia azonao atao ny mitazona ny fahafahan'ny fisaintsainana sy ny hafainganam-pandehan'ny fampiharana.

Hita eto ny code benchmark. Na iza na iza dia afaka manamarina ny teniko:
HabraReflectionTests

PS: Ny kaody amin'ny fitsapana dia mampiasa IoC, ary ao amin'ny benchmark dia mampiasa fananganana mazava. Ny zava-misy dia amin'ny fampiharana farany aho dia nanapaka ny lafin-javatra rehetra izay mety hisy fiantraikany amin'ny fampisehoana ary mahatonga ny vokatra ho tabataba.

PPS: Misaotra ny mpampiasa Dmitry Tikhonov @0x1000000 noho ny fahitana ny fahadisoako tamin'ny fametrahana Moq, izay nisy fiantraikany tamin'ny fandrefesana voalohany. Raha misy amin'ireo mpamaky manana karma ampy dia miangavy anao hanao j'aime. Nijanona ilay lehilahy, namaky ilay lehilahy, nanamarina indroa ilay lehilahy ary nanondro ny fahadisoana. Heveriko fa mendrika ny hajaina sy ny fiaraha-miory izany.

PPPS: misaotra ny mpamaky malina izay tonga hatrany amin'ny faran'ny fomba sy ny famolavolana. Izaho dia noho ny fanamiana sy ny fanamorana. Ny diplaomasia amin'ny famelabelarana dia mamela betsaka, saingy noraisiko ny fanakianana. Mangataka ny projectile aho.

Source: www.habr.com

Add a comment