د انعکاس د چټکتیا په اړه ناکامه مقاله

زه به سمدلاسه د مقالې سرلیک تشریح کړم. اصلي پلان دا و چې د ساده مګر ریښتیني مثال په کارولو سره د انعکاس کارولو ګړندۍ کولو څرنګوالي په اړه ښه ، معتبر مشوره ورکول و ، مګر د بنچمارک کولو په جریان کې دا معلومه شوه چې انعکاس دومره ورو ندی لکه څنګه چې ما فکر کاوه ، LINQ زما د خوبونو په پرتله ورو دی. مګر په پای کې دا معلومه شوه چې ما هم په اندازه کولو کې غلطي کړې ... د دې ژوند کیسه جزئیات د کټ لاندې او په نظرونو کې دي. څرنګه چې مثال خورا عام دی او په اصولو کې پلي کیږي لکه څنګه چې معمولا په تصدۍ کې ترسره کیږي ، دا خورا په زړه پوري وګرځید ، لکه څنګه چې ماته ښکاري ، د ژوند څرګندونه: د مقالې اصلي موضوع سرعت باندې اغیزه د بهرني منطق له امله د پام وړ ندي: Moq، Autofac، EF Core او نور "بندینګونه".

ما د دې مقالې تر تاثیر لاندې کار پیل کړ: ولې انعکاس ورو دی

لکه څنګه چې تاسو لیدلی شئ ، لیکوال وړاندیز کوي د تالیف شوي استازو کارولو پرځای د مستقیم انعکاس ډول میتودونو ته د غوښتنلیک د ګړندي کولو عالي لاره په توګه. البته، د IL اخراج شتون لري، مګر زه غواړم له دې څخه مخنیوی وکړم، ځکه چې دا د دندې ترسره کولو لپاره خورا سخت کار دی، کوم چې له غلطیو ډک دی.

د دې په پام کې نیولو سره چې ما تل د انعکاس سرعت په اړه ورته نظر درلود، ما په ځانګړې توګه د لیکوال د پایلو په اړه د پوښتنې کولو اراده نه درلوده.

زه ډیری وختونه په تصدۍ کې د انعکاس ساده کارولو سره مخ کیږم. ډول اخیستل کیږي. د ملکیت په اړه معلومات اخیستل کیږي. د SetValue میتود ویل کیږي او هرڅوک خوښیږي. ارزښت د هدف ساحې ته رسیدلی، هرڅوک خوشحاله دي. ډیر هوښیار خلک - مشران او د ټیم مشران - د اعتراض لپاره خپل توسیعونه لیکي، د داسې ساده تطبیق "نړیوال" نقشې پر بنسټ یو ډول بل ته. جوهر معمولا دا دی: موږ ټولې ساحې اخلو ، ټول ملکیتونه اخلو ، په دوی باندې تکرار کوو: که د ډول غړو نومونه سره سمون ولري ، موږ SetValue اجرا کوو. د وخت په تیریدو سره موږ د غلطیو له امله استثناوې نیسو چیرې چې موږ په یو ډول کې ځینې ملکیت ونه موندلو، مګر حتی دلته یوه لاره شتون لري چې فعالیت ته وده ورکوي. هڅه وکړئ / ونیسئ.

ما ولیدل چې خلک پرته له دې چې په بشپړ ډول د معلوماتو سره سمبال شوي پارسرونه او نقشه نوي کړي چې څنګه ماشینونه چې د دوی څخه مخکې راغلي وو کار کوي. ما لیدلي چې خلک د ستراتیژیو تر شا، د انټرفیسونو تر شا، د انجیکونو تر شا خپل بې پرواه پلي کول پټوي، لکه څنګه چې دا به د راتلونکي بیکانالیا عذر وکړي. ما په داسې واقعیتونو خپله پزه پورته کړه. په حقیقت کې ، ما د ریښتیني فعالیت لیک اندازه نه ده کړې ، او که امکان ولري ، ما په ساده ډول پلي کول ډیر "غوره" ته بدل کړل که زه وکولی شم خپل لاسونه پرې ترلاسه کړم. له همدې امله ، لومړی اندازه چې لاندې بحث شوي زه په جدي ډول مغشوش کړم.

زه فکر کوم چې ستاسو څخه ډیری ، د ریکټر یا نورو ایډیالوژیستانو لوستل ، په بشپړ ډول منصفانه بیان کې راغلي چې په کوډ کې انعکاس یوه پدیده ده چې د غوښتنلیک په فعالیت خورا منفي اغیزه لري.

د انعکاس زنګ وهل CLR مجبوروي چې د مجلسونو له لارې لاړ شي ترڅو هغه ومومي چې دوی ورته اړتیا لري ، د دوی میټاډاټا راوباسي ، تحلیل یې کړي ، او داسې نور. برسېره پردې، انعکاس پداسې حال کې چې د ترتیبونو څخه تیریږي د لوی مقدار حافظې تخصیص لامل کیږي. موږ حافظه کاروو، CLR GC افشا کوي او فریزونه پیل کیږي. دا باید د پام وړ ورو وي، باور وکړئ. په عصري تولید سرورونو یا کلاوډ ماشینونو کې د حافظې لوی مقدار د لوړ پروسس ځنډ مخه نه نیسي. په حقیقت کې، څومره چې حافظه ډیره وي، هغومره به تاسو په دې پوه شئ چې GC څنګه کار کوي. انعکاس، په تیوري کې، د هغه لپاره یو اضافي سور ریګ دی.

په هرصورت، موږ ټول د IoC کانټینرونه او د نیټې نقشه کاروو، د عملیاتي اصول چې د انعکاس پر بنسټ والړ دی، مګر معمولا د دوی د فعالیت په اړه هیڅ پوښتنې شتون نلري. نه، نه دا چې د انحصار معرفي کول او د بهرني محدود شرایطو ماډلونو څخه خلاصول دومره اړین دي چې موږ باید په هر حالت کې د فعالیت قرباني کړو. هرڅه ساده دي - دا واقعیا په فعالیت ډیر اغیزه نلري.

حقیقت دا دی چې خورا عام چوکاټونه چې د انعکاس ټیکنالوژۍ پراساس دي هر ډول چلونه کاروي ترڅو د دې سره ډیر ښه کار وکړي. معمولا دا یوه زیرمه ده. په عموم کې دا څرګندونې او استازي دي چې د بیان ونې څخه راټول شوي. ورته اتوماتیک یو رقابتي قاموس ساتي چې ډولونه د افعالونو سره سمون لري چې کولی شي د انعکاس زنګ وهلو پرته یو بل ته بدل کړي.

دا څنګه ترلاسه کیږي؟ په لازمي ډول ، دا د منطق څخه توپیر نلري چې پلیټ فارم پخپله د JIT کوډ رامینځته کولو لپاره کاروي. کله چې یو میتود د لومړي ځل لپاره ویل کیږي، دا تالیف شوی (او، هو، دا پروسه ګړندۍ نه ده)؛ په راتلونکو تلیفونونو کې، کنټرول دمخه ترتیب شوي میتود ته لیږدول کیږي، او د پام وړ فعالیت کمښت به شتون ونلري.

زموږ په قضیه کې، تاسو کولی شئ د JIT تالیف هم وکاروئ او بیا د ورته فعالیت سره د AOT همکارانو په څیر تالیف شوي چلند وکاروئ. څرګندونې به په دې قضیه کې زموږ مرستې ته راشي.

د پوښتنې اصول په لنډ ډول په لاندې ډول ترتیب کیدی شي:
تاسو باید د انعکاس وروستۍ پایله د یوه استازي په توګه وساتئ چې تالیف شوي فنکشن لري. دا هم معنی لري چې ټول اړین توکي د ډول معلوماتو سره ستاسو د ډول ، کارګر په برخو کې ذخیره کړئ چې د توکو څخه بهر زیرمه شوي.

پدې کې منطق شتون لري. عام احساس موږ ته وايي چې که یو څه تالیف او زیرمه شي، نو باید ترسره شي.

مخکې لټولو، دا باید وویل شي چې د انعکاس سره کار کولو کې کیچ خپلې ګټې لري، حتی که تاسو د بیان کولو وړاندیز شوي میتود نه کاروئ. په حقیقت کې، دلته زه په ساده ډول د مقالې د لیکوال مقالې تکراروم کوم چې زه پورته اشاره کوم.

اوس د کوډ په اړه. راځئ چې یو مثال وګورو چې زما د وروستي درد پراساس دی چې ما د یو جدي کریډیټ موسسې په جدي تولید کې مخامخ کړی و. ټولې ادارې فرضي دي نو هیڅوک به یې اټکل ونه کړي.

یو څه جوهر شتون لري. اجازه راکړئ چې اړیکه وي. د معیاري بدن سره لیکونه شتون لري چې له هغې څخه پارسر او هایډرټر ورته اړیکې رامینځته کوي. یو لیک راورسید، موږ یې ولوستل، د کلیدي ارزښتونو په جوړه کې یې تجزیه کړه، اړیکه یې جوړه کړه، او په ډیټابیس کې یې خوندي کړه.

دا ابتدايي ده. راځئ چې ووایو چې اړیکه د بشپړ نوم ، عمر او اړیکې تلیفون ملکیتونه لري. دا معلومات په لیک کې لیږدول کیږي. سوداګري هم ملاتړ غواړي ترڅو وکوالی شي په چټکۍ سره د لیک په بدن کې جوړه جوړه د ادارې ملکیتونو نقشه کولو لپاره نوي کیلي اضافه کړي. په هغه صورت کې چې یو څوک په ټیمپلیټ کې ټایپ کړي یا که د خوشې کیدو دمخه دا اړینه ده چې په سمدستي توګه د نوي ملګري څخه نقشه پیل کړئ ، نوي فارمیټ ته تطبیق کړئ. بیا موږ کولی شو د ارزانه ډیټا فکس په توګه د نقشه کولو نوې اړیکه اضافه کړو. دا د ژوند مثال دی.

موږ تطبیق کوو، ازموینې رامینځته کوو. کار کوي.

زه به کوډ چمتو نه کړم: ډیری سرچینې شتون لري، او دوی د مقالې په پای کې د لینک له لارې په GitHub کې شتون لري. تاسو کولی شئ دوی پورته کړئ، دوی د پیژندلو څخه بهر شکنجه کړئ او اندازه یې کړئ، ځکه چې دا به ستاسو په قضیه اغیزه وکړي. زه به یوازې د دوه ټیمپلیټ میتودونو کوډ ورکړم چې د هایډریټر توپیر کوي ، کوم چې باید ګړندی وي ، له هایډریټر څخه ، کوم چې باید ورو وي.

منطق په لاندې ډول دی: د ټیمپلیټ میتود د بنسټیز پارسر منطق لخوا رامینځته شوي جوړه ترلاسه کوي. د LINQ پرت پارسر او د هایډریټر اساسي منطق دی، کوم چې د ډیټابیس شرایطو ته غوښتنه کوي او کیلي د پارسر څخه جوړه سره پرتله کوي (د دې دندو لپاره د پرتله کولو لپاره د LINQ پرته کوډ شتون لري). بیا ، جوړه د هایډریشن اصلي میتود ته لیږدول کیږي او د جوړه ارزښتونه د ادارې اړوند ملکیتونو ته ټاکل کیږي.

"چټک" (په بنچمارکونو کې د مخکینۍ چټکتیا):

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

لکه څنګه چې موږ لیدلی شو، د سیټر ملکیتونو سره یو جامد ټولګه کارول کیږي - تالیف شوی لامبډاس چې د سیټر اداره بولي. د لاندې کوډ لخوا رامینځته شوی:

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

په عمومي توګه دا روښانه ده. موږ ملکیتونه وګرځوو، د دوی لپاره استازي جوړ کړو چې سیټرانو ته زنګ ووهي او خوندي یې کړي. بیا موږ د اړتیا په وخت تلیفون کوو.

"ورو" (په بنچمارکونو کې ورو ورو مخکینۍ):

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

دلته موږ سمدلاسه ملکیتونه بای پاس کوو او مستقیم SetValue ته زنګ وهو.

د وضاحت لپاره او د یوې مرجع په توګه، ما یو ساده میتود پلي کړ چې د دوی د اړیکو جوړې ارزښتونه په مستقیم ډول د ادارې ساحو ته لیکي. مخفف - لارښود.

اوس راځئ چې BenchmarkDotNet واخلو او فعالیت معاینه کړو. او ناڅاپه ... (سپیلر - دا سمه پایله نه ده، توضیحات لاندې دي)

د انعکاس د چټکتیا په اړه ناکامه مقاله

موږ دلته څه وینو؟ هغه ميتودونه چې په برياليتوب سره ګړندي مختګ لري په نږدې ټولو پاسونو کې د ورو مخفف سره د ميتودونو په پرتله ورو وي. دا د کار سرعت او تخصیص دواړو لپاره ریښتیا ده. له بلې خوا، د LINQ میتودونو په کارولو سره د نقشه کولو یو ښکلی او په زړه پوری پلي کول د دې لپاره ټاکل شوي چیرې چې امکان ولري ، برعکس ، د تولید کچه خورا کموي. توپیر په ترتیب کې دی. رجحان د پاسونو مختلف شمیر سره بدلون نه کوي. یوازینی توپیر په پیمانه کې دی. د LINQ سره دا 4 - 200 ځله ورو دی، نږدې په ورته پیمانه ډیر کثافات شتون لري.

واړوله

ما په خپلو سترګو باور نه درلود، مګر تر ټولو مهم، زموږ همکار زما په سترګو یا زما کوډ باور نه درلود - دمیتري تیخونوف 0x1000000. زما د حل دوه ځله چک کولو سره، هغه په ​​​​زړه پورې یوه تېروتنه وموندله او په ګوته کړه چې ما په پلي کولو کې د یو شمیر بدلونونو له امله له لاسه ورکړې، له پیل څخه تر وروستي پورې. د Moq په ترتیب کې د موندل شوي بګ له حل کولو وروسته، ټولې پایلې په ځای کې راوتلې. د بیاکتنې پایلو په وینا، اصلي رجحان بدلون نه کوي - LINQ لاهم د انعکاس څخه ډیر فعالیت اغیزه کوي. په هرصورت، دا ښه ده چې د بیان تالیف سره کار بې ګټې نه دی ترسره شوی، او پایله دواړه د تخصیص او اجرا کولو وخت کې لیدل کیږي. لومړی لانچ، کله چې جامد ساحې پیل شي، په طبیعي توګه د "چټک" میتود لپاره ورو وي، مګر بیا وضعیت بدلیږي.

دلته د بیا ازموینې پایله ده:

د انعکاس د چټکتیا په اړه ناکامه مقاله

پایله: کله چې په یوه تصدۍ کې انعکاس وکاروئ ، نو د چلونو څخه کار اخیستلو ته کومه ځانګړې اړتیا نشته - LINQ به ډیر تولید وخوري. په هرصورت، د لوړ بار میتودونو کې چې اصلاح ته اړتیا لري، تاسو کولی شئ د ابتدایي او استازو تالیف کونکو په بڼه انعکاس خوندي کړئ، چې بیا به "چټک" منطق چمتو کړي. پدې توګه تاسو کولی شئ د انعکاس انعطاف او د غوښتنلیک سرعت دواړه وساتئ.

د بنچمارک کوډ دلته شتون لري. هر څوک کولی شي زما خبرې دوه ځله وګوري:
HabraReflectionTests

PS: په ازموینو کې کوډ IoC کاروي، او په بنچمارکونو کې دا روښانه جوړښت کاروي. حقیقت دا دی چې په وروستي تطبیق کې ما ټول هغه فاکتورونه پرې کړل چې کولی شي په فعالیت اغیزه وکړي او پایله یې شور جوړ کړي.

PPS: د کارونکي څخه مننه دمیتري تیخونوف @0x1000000 د Moq په ترتیب کولو کې زما د تېروتنې موندلو لپاره، کوم چې لومړی اندازه اغیزه کړې. که کوم لوستونکي کافي کرامت ولري، لطفا یې خوښ کړئ. سړی ودرېد، سړي ولوستل، سړي دوه ځله وکتل او تېروتنه یې په ګوته کړه. زه فکر کوم چې دا د درناوي او خواخوږۍ وړ دی.

PPPS: د دقیق لوستونکي څخه مننه چې د سټایل او ډیزاین پای ته رسیدلی. زه د یووالي او اسانتیا لپاره یم. د پریزنټشن ډیپلوماسۍ د غوښتلو لپاره ډیر څه پریږدي ، مګر ما انتقاد په پام کې نیولی. زه د پروجیکل غوښتنه کوم.

سرچینه: www.habr.com

Add a comment