Dili malampuson nga artikulo bahin sa pagpadali sa pagpamalandong

Ipasabot dayon nako ang ulohan sa artikulo. Ang orihinal nga plano mao ang paghatag og maayo, kasaligan nga tambag kon unsaon pagpadali ang paggamit sa pagpamalandong gamit ang usa ka yano apan realistiko nga panig-ingnan, apan sa panahon sa benchmarking nahimo nga ang pagpamalandong dili ingon ka hinay sa akong gihunahuna, ang LINQ mas hinay kaysa sa akong mga damgo. Apan sa katapusan nahimo nga nasayop usab ako sa mga sukod ... Ang mga detalye niini nga istorya sa kinabuhi naa sa ubos ug sa mga komento. Tungod kay ang panig-ingnan kay kasagaran ug gipatuman sa prinsipyo sama sa kasagaran nga gihimo sa usa ka negosyo, kini nahimo nga usa ka makapaikag, ingon nga alang kanako, demonstrasyon sa kinabuhi: ang epekto sa katulin sa nag-unang hilisgutan sa artikulo mao ang dili mamatikdan tungod sa external logic: Moq, Autofac, EF Core ug uban pa nga "strap".

Nagsugod ako sa pagtrabaho ubos sa impresyon niini nga artikulo: Nganong hinay ang Reflection

Sama sa imong makita, gisugyot sa tagsulat ang paggamit sa mga hinipos nga mga delegado imbis nga direkta nga tawagan ang mga pamaagi sa tipo sa pagpamalandong ingon usa ka maayong paagi aron mapadali ang aplikasyon. Adunay, siyempre, ang pagpagawas sa IL, apan gusto nako nga likayan kini, tungod kay kini ang labing kusog nga pagtrabaho nga paagi aron mahimo ang buluhaton, nga puno sa mga sayup.

Sa pagkonsiderar nga kanunay akong naghupot sa parehas nga opinyon bahin sa katulin sa pagpamalandong, wala gyud nako tuyoa ang pagpangutana sa mga konklusyon sa tagsulat.

Kanunay kong makasugat og walay pulos nga paggamit sa pagpamalandong sa negosyo. Gikuha ang tipo. Ang impormasyon bahin sa kabtangan gikuha. Ang SetValue nga pamaagi gitawag ug ang tanan nalipay. Ang bili miabut sa target nga natad, ang tanan malipayon. Maalamon kaayo nga mga tawo - mga tigulang ug nanguna sa team - isulat ang ilang mga extension sa pagsupak, nga gibase sa ingon nga usa ka walay pulos nga pagpatuman nga "universal" nga mga mapper sa usa ka tipo ngadto sa lain. Ang esensya sa kasagaran mao kini: gikuha namon ang tanan nga mga uma, gikuha ang tanan nga mga kabtangan, gisubli kini: kung ang mga ngalan sa tipo nga mga miyembro magkatugma, among gipatuman ang SetValue. Matag karon ug unya nakakuha kami mga eksepsiyon tungod sa mga kasaypanan diin wala kami makit-an nga mga kabtangan sa usa sa mga tipo, apan bisan dinhi adunay usa ka paagi sa paggawas nga nagpauswag sa pasundayag. Sulayi / dakpon.

Nakita nako ang mga tawo nga nag-imbento pag-usab sa mga parser ug mapper nga wala hingpit nga armado sa kasayuran kung giunsa ang mga makina nga nag-una kanila nagtrabaho. Nakita nako ang mga tawo nga nagtago sa ilang mga walay pulos nga pagpatuman sa luyo sa mga estratehiya, luyo sa mga interface, luyo sa mga injection, ingon nga kini makapangita sa sunod nga bacchanalia. Gipataas nako ang akong ilong sa ingon nga mga pagkaamgo. Sa tinuud, wala nako gisukod ang tinuud nga pagtulo sa pasundayag, ug, kung mahimo, gibag-o ra nako ang pagpatuman sa usa ka labi ka "optimal" kung makuha nako ang akong mga kamot. Busa, ang unang mga sukod nga gihisgotan sa ubos seryosong nakapalibog kanako.

Sa akong hunahuna daghan kaninyo, nga nagbasa Richter o uban pang mga ideologo, nakakita sa usa ka hingpit nga patas nga pahayag nga ang pagpamalandong sa code usa ka panghitabo nga adunay labi ka negatibo nga epekto sa paghimo sa aplikasyon.

Ang pagpamalandong sa pagtawag nagpugos sa CLR sa pag-agi sa mga asembliya aron pangitaon ang ilang gikinahanglan, pagbitad sa ilang metadata, pag-parse kanila, ug uban pa. Dugang pa, ang pagpamalandong samtang nagsubay sa mga han-ay nagdala ngadto sa alokasyon sa usa ka dako nga kantidad sa panumduman. Naggamit kami sa memorya, gibuksan sa CLR ang GC ug nagsugod ang mga friez. Kini kinahanglan nga mamatikdan nga hinay, tuohi ako. Ang dako nga kantidad sa panumduman sa modernong mga server sa produksiyon o mga makina sa panganod wala makapugong sa taas nga mga paglangan sa pagproseso. Sa pagkatinuod, ang mas daghang memorya, mas lagmit nga imong mamatikdan kung giunsa ang GC nagtrabaho. Ang pagpamalandong, sa teorya, usa ka dugang nga pula nga trapo alang kaniya.

Bisan pa, kaming tanan naggamit sa mga sulud sa IoC ug mga mapa sa petsa, ang prinsipyo sa operasyon nga gibase usab sa pagpamalandong, apan kasagaran wala’y mga pangutana bahin sa ilang nahimo. Dili, dili tungod kay ang pagpaila sa mga dependency ug abstraction gikan sa gawas nga limitado nga mga modelo sa konteksto gikinahanglan kaayo nga kinahanglan natong isakripisyo ang pasundayag sa bisan unsang kaso. Ang tanan mas simple - kini dili kaayo makaapekto sa performance.

Ang tinuod mao nga ang labing kasagaran nga mga balangkas nga gibase sa teknolohiya sa pagpamalandong naggamit sa tanan nga mga lahi sa mga limbong aron magamit kini nga labi ka maayo. Kasagaran kini usa ka cache. Kasagaran kini ang mga Expression ug mga delegado nga gihugpong gikan sa punoan sa ekspresyon. Ang parehas nga automapper nagmintinar sa usa ka kompetisyon nga diksyonaryo nga nagpares sa mga tipo nga adunay mga gimbuhaton nga mahimo’g mabag-o ang usag usa nga wala’y pagtawag sa pagpamalandong.

Giunsa kini pagkab-ot? Sa tinuud, wala kini lahi sa lohika nga gigamit mismo sa plataporma aron makamugna ang JIT code. Kung ang usa ka pamaagi gitawag sa unang higayon, kini gihugpong (ug, oo, kini nga proseso dili paspas); sa sunod nga mga tawag, ang kontrol gibalhin ngadto sa naipon na nga pamaagi, ug walay mahinungdanon nga performance drawdowns.

Sa among kaso, mahimo usab nimo gamiton ang JIT compilation ug dayon gamiton ang gihugpong nga kinaiya nga adunay parehas nga pasundayag sa mga katugbang niini sa AOT. Ang mga ekspresyon motabang kanato niining kasoha.

Ang prinsipyo nga gipangutana mahimong maporma sa mubo ingon sa mosunod:
Kinahanglan nimo nga i-cache ang katapusang resulta sa pagpamalandong isip usa ka delegado nga adunay sulod nga gihugpong nga function. Makatarunganon usab nga i-cache ang tanan nga kinahanglan nga mga butang nga adunay kasayuran sa tipo sa mga natad sa imong tipo, ang trabahante, nga gitipigan sa gawas sa mga butang.

Adunay lohika niini. Ang sentido komon nagsulti kanato nga kung ang usa ka butang mahimo nga matipon ug ma-cache, nan kini kinahanglan nga buhaton.

Sa pagtan-aw sa unahan, kinahanglan nga isulti nga ang cache sa pagtrabaho uban ang pagpamalandong adunay mga bentaha, bisan kung wala nimo gigamit ang gisugyot nga pamaagi sa pagtipon sa mga ekspresyon. Sa tinuud, ania ako yano nga gisubli ang mga tesis sa tagsulat sa artikulo nga akong gipasabut sa taas.

Karon mahitungod sa code. Atong tan-awon ang usa ka pananglitan nga gibase sa akong bag-o nga kasakit nga kinahanglan nakong atubangon sa usa ka seryoso nga produksyon sa usa ka seryoso nga institusyon sa kredito. Ang tanan nga mga entidad tinumotumo lamang aron walay makatag-an.

Adunay pipila ka esensya. Himoa nga adunay Contact. Adunay mga letra nga adunay usa ka standardized nga lawas, diin ang parser ug hydrator naghimo niining parehas nga mga kontak. Usa ka sulat ang miabut, among gibasa kini, gi-parse kini ngadto sa key-value pairs, naghimo og kontak, ug gitipigan kini sa database.

Elementary na nga. Ingnon ta nga ang usa ka kontak adunay mga kabtangan Tibuok Ngalan, Edad ug Telepono sa Kontak. Kini nga datos gipasa sa sulat. Gusto usab sa negosyo ang suporta aron dali nga makadugang mga bag-ong yawe alang sa pagmapa sa mga kabtangan sa entidad sa mga pares sa lawas sa sulat. Sa kaso nga adunay usa nga naghimo sa usa ka typo sa template o kung sa wala pa ang pagpagawas kinahanglan nga dinalian nga maglunsad og mapping gikan sa usa ka bag-ong kauban, nga mopahiangay sa bag-ong format. Dayon makadugang kami og bag-ong mapping correlation isip barato nga datafix. Sa ato pa, usa ka ehemplo sa kinabuhi.

Nagpatuman kami, naghimo og mga pagsulay. Mga buhat.

Dili nako ihatag ang code: adunay daghang mga gigikanan, ug kini magamit sa GitHub pinaagi sa link sa katapusan sa artikulo. Mahimo nimo silang i-load, torture sila nga dili mailhan ug sukdon sila, ingon nga makaapekto kini sa imong kaso. Ihatag lang nako ang code sa duha ka pamaagi sa template nga nagpalahi sa hydrator, nga dali ra kuno, gikan sa hydrator, nga hinay ra kuno.

Ang lohika mao ang mosunod: ang template nga pamaagi makadawat og mga pares nga namugna sa batakang parser logic. Ang LINQ layer mao ang parser ug ang batakang lohika sa hydrator, nga naghimo sa usa ka hangyo sa konteksto sa database ug nagtandi sa mga yawe sa mga pares gikan sa parser (alang niini nga mga gimbuhaton adunay code nga walay LINQ alang sa pagtandi). Sunod, ang mga pares gipasa sa panguna nga pamaagi sa hydration ug ang mga kantidad sa mga pares gitakda sa katugbang nga mga kabtangan sa entidad.

"Pagpuasa" (Prefix Fast sa mga 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;
        }

Sama sa atong makita, ang usa ka static nga koleksyon nga adunay mga kabtangan sa setter gigamit - gihugpong nga mga lambdas nga nagtawag sa setter entity. Gihimo pinaagi sa mosunod nga code:

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

Sa kinatibuk-an kini klaro. Among gisubay ang mga kabtangan, naghimo og mga delegado alang kanila nga nagtawag sa mga setter, ug gitipigan sila. Unya motawag mi kon gikinahanglan.

"Mahinay" (Prefix Mahinay sa mga benchmark):

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

Dinhi atong laktawan dayon ang mga kabtangan ug direktang tawagan ang SetValue.

Alang sa katin-awan ug ingon usa ka pakisayran, gipatuman nako ang usa ka wala’y hinungdan nga pamaagi nga nagsulat sa mga kantidad sa ilang mga pares sa correlation direkta sa mga natad sa entidad. Prefix – Manwal.

Karon atong kuhaon ang BenchmarkDotNet ug susihon ang pasundayag. Ug sa kalit... (spoiler - dili kini ang husto nga resulta, ang mga detalye anaa sa ubos)

Dili malampuson nga artikulo bahin sa pagpadali sa pagpamalandong

Unsay atong makita dinhi? Ang mga pamaagi nga madaugon nga nagdala sa Fast prefix nahimong mas hinay sa halos tanang pass kaysa mga pamaagi nga adunay Slow prefix. Tinuod kini alang sa alokasyon ug katulin sa trabaho. Sa laing bahin, ang usa ka matahum ug elegante nga pagpatuman sa pagmapa gamit ang mga pamaagi sa LINQ nga gituyo alang niini kung mahimo, sa sukwahi, labi nga nagpamenos sa produktibo. Ang kalainan kay sa kahusay. Ang uso dili mausab sa lain-laing mga gidaghanon sa mga pass. Ang kalainan lang kay sa scale. Uban sa LINQ kini 4 - 200 ka beses nga hinay, adunay daghang basura sa gibana-bana nga parehas nga sukod.

Updated

Wala ko motuo sa akong mga mata, apan labaw sa tanan, ang among kauban wala motuo sa akong mga mata o sa akong code - Dmitry Tikhonov 0x1000000. Sa pag-double-check sa akong solusyon, maayo niyang nadiskobrehan ug gipunting ang usa ka sayup nga akong gimingaw tungod sa daghang mga pagbag-o sa pagpatuman, una hangtod sa katapusan. Pagkahuman sa pag-ayo sa nakit-an nga bug sa setup sa Moq, ang tanan nga mga resulta nahulog sa lugar. Sumala sa mga resulta sa retest, ang nag-unang uso dili mausab - ang LINQ makaapekto gihapon sa pasundayag labaw pa sa pagpamalandong. Bisan pa, maayo nga ang trabaho nga adunay pag-compile sa Expression wala gihimo nga kawang, ug ang resulta makita sa alokasyon ug oras sa pagpatuman. Ang una nga paglansad, kung gisugdan ang mga static nga natad, natural nga labi ka hinay alang sa "paspas" nga pamaagi, apan pagkahuman nabag-o ang kahimtang.

Ania ang resulta sa retest:

Dili malampuson nga artikulo bahin sa pagpadali sa pagpamalandong

Konklusyon: kung gigamit ang pagpamalandong sa usa ka negosyo, wala’y partikular nga kinahanglan nga mogamit sa mga limbong - ang LINQ mas mokaon sa pagka-produktibo. Bisan pa, sa mga pamaagi nga adunay taas nga karga nga nanginahanglan pag-optimize, mahimo nimong i-save ang pagpamalandong sa porma sa mga inisyal ug delegado nga mga compiler, nga maghatag "paspas" nga lohika. Niining paagiha mapadayon nimo ang pagka-flexible sa pagpamalandong ug ang katulin sa aplikasyon.

Ang benchmark code anaa dinhi. Bisan kinsa nga makasusi sa akong mga pulong:
Mga Pagsulay sa HabraReflection

PS: ang code sa mga pagsulay naggamit sa IoC, ug sa mga benchmark naggamit kini usa ka klaro nga pagtukod. Ang tinuod mao nga sa katapusan nga pagpatuman akong giputol ang tanan nga mga hinungdan nga makaapekto sa pasundayag ug maghimo sa resulta nga saba.

PPS: Salamat sa tiggamit Dmitry Tikhonov @0x1000000 sa pagdiskobre sa akong sayop sa pag-set up sa Moq, nga nakaapekto sa unang mga sukod. Kung bisan kinsa sa mga magbabasa adunay igo nga karma, palihug i-like kini. Mihunong ang tawo, gibasa sa lalaki, gi-double check sa lalaki ug gitudlo ang sayup. Sa akong hunahuna kini takus sa pagtahod ug simpatiya.

PPPS: salamat sa makuti nga magbabasa nga nakakuha sa ilawom sa istilo ug disenyo. Ako alang sa pagkaparehas ug kasayon. Ang diplomasya sa presentasyon nagbilin ug daghan nga gitinguha, apan akong gikonsiderar ang pagsaway. Nangayo ko sa projectile.

Source: www.habr.com

Idugang sa usa ka comment