عکاسی کو تیز کرنے کے بارے میں ناکام مضمون

میں فوری طور پر مضمون کے عنوان کی وضاحت کروں گا۔ اصل منصوبہ ایک سادہ لیکن حقیقت پسندانہ مثال کا استعمال کرتے ہوئے عکاسی کے استعمال کو تیز کرنے کے بارے میں اچھا، قابل اعتماد مشورہ دینا تھا، لیکن بینچ مارکنگ کے دوران یہ پتہ چلا کہ عکاسی اتنی سست نہیں ہے جتنا میں نے سوچا تھا، LINQ میرے ڈراؤنے خوابوں کی نسبت سست ہے۔ لیکن آخر میں پتہ چلا کہ پیمائش میں مجھ سے بھی غلطی ہوئی... اس زندگی کی کہانی کی تفصیلات کٹ کے نیچے اور کمنٹس میں ہیں۔ چونکہ مثال کافی عام ہے اور اصولی طور پر لاگو کیا جاتا ہے جیسا کہ عام طور پر ایک انٹرپرائز میں کیا جاتا ہے، یہ کافی دلچسپ نکلا، جیسا کہ مجھے لگتا ہے، زندگی کا مظاہرہ: مضمون کے مرکزی مضمون کی رفتار پر اثر بیرونی منطق کی وجہ سے قابل توجہ نہیں: Moq، Autofac، EF Core اور دیگر "bandings"۔

میں نے اس مضمون کے تاثر کے تحت کام شروع کیا: عکاسی سست کیوں ہے؟

جیسا کہ آپ دیکھ سکتے ہیں، مصنف نے براہ راست عکاسی قسم کے طریقوں کو کال کرنے کے بجائے مرتب کردہ مندوبین کو استعمال کرنے کا مشورہ دیا ہے تاکہ ایپلی کیشن کو تیز کرنے کا ایک بہترین طریقہ ہو۔ یقیناً IL کا اخراج ہے، لیکن میں اس سے بچنا چاہوں گا، کیونکہ یہ کام انجام دینے کا سب سے زیادہ محنت طلب طریقہ ہے، جو کہ غلطیوں سے بھرا ہوا ہے۔

اس بات پر غور کرتے ہوئے کہ میں عکاسی کی رفتار کے بارے میں ہمیشہ ایک جیسی رائے رکھتا ہوں، میرا خاص طور پر مصنف کے نتائج پر سوال اٹھانے کا ارادہ نہیں تھا۔

مجھے اکثر انٹرپرائز میں عکاسی کے سادہ استعمال کا سامنا کرنا پڑتا ہے۔ قسم لی جاتی ہے۔ جائیداد کے بارے میں معلومات لی جاتی ہیں۔ SetValue طریقہ کہا جاتا ہے اور ہر کوئی خوش ہوتا ہے۔ ٹارگٹ فیلڈ میں قدر آ گئی، سب خوش ہیں۔ بہت ہوشیار لوگ - سینئرز اور ٹیم لیڈز - اپنی ایکسٹینشنز کو اعتراض کے لیے لکھتے ہیں، اس طرح کے سادہ نفاذ کی بنیاد پر "یونیورسل" میپرز ایک قسم کے دوسرے سے۔ جوہر عام طور پر یہ ہے: ہم تمام فیلڈز لیتے ہیں، تمام پراپرٹیز لیتے ہیں، ان پر اعادہ کرتے ہیں: اگر قسم کے اراکین کے نام مماثل ہیں، تو ہم SetValue کو عمل میں لاتے ہیں۔ وقتا فوقتا ہم غلطیوں کی وجہ سے مستثنیات کو پکڑتے ہیں جہاں ہمیں کسی ایک قسم میں کچھ خاصیت نہیں ملی، لیکن یہاں بھی ایک طریقہ ہے جو کارکردگی کو بہتر بناتا ہے۔ پکڑنے کی کوشش.

میں نے لوگوں کو مکمل طور پر اسلحے سے لیس کیے بغیر پارسر اور میپرز کو دوبارہ ایجاد کرتے ہوئے دیکھا ہے کہ ان سے پہلے آنے والی مشینیں کیسے کام کرتی ہیں۔ میں نے دیکھا ہے کہ لوگوں کو حکمت عملیوں کے پیچھے، انٹرفیس کے پیچھے، انجیکشن کے پیچھے ان کے سادہ عمل کو چھپاتے ہیں، گویا اس سے بعد میں آنے والے بچنالیا کو معاف کر دیا جائے گا۔ میں نے اس طرح کے احساس پر اپنی ناک موڑ لی۔ درحقیقت، میں نے حقیقی کارکردگی کے رساو کی پیمائش نہیں کی، اور، اگر ممکن ہو تو، میں نے نفاذ کو صرف ایک زیادہ "زیادہ سے زیادہ" میں تبدیل کر دیا اگر میں اس پر ہاتھ ڈال سکتا ہوں۔ لہذا، ذیل میں زیر بحث پہلی پیمائش نے مجھے سنجیدگی سے الجھا دیا۔

میرا خیال ہے کہ آپ میں سے بہت سے لوگ، ریکٹر یا دیگر نظریاتی ماہرین کو پڑھتے ہوئے، ایک مکمل طور پر منصفانہ بیان پر پہنچے ہیں کہ کوڈ میں عکاسی ایک ایسا رجحان ہے جس کا اطلاق کی کارکردگی پر انتہائی منفی اثر پڑتا ہے۔

عکاسی کو کال کرنا CLR کو اسمبلیوں سے گزرنے پر مجبور کرتا ہے تاکہ وہ اپنی ضرورت کی تلاش کریں، ان کا میٹا ڈیٹا کھینچیں، ان کی تجزیہ کریں وغیرہ۔ اس کے علاوہ، تسلسل کو عبور کرتے ہوئے عکاسی میموری کی ایک بڑی مقدار کو مختص کرنے کا باعث بنتی ہے۔ ہم میموری استعمال کر رہے ہیں، CLR نے GC کو بے نقاب کیا اور فریز شروع ہو گئے۔ یہ کافی سست ہونا چاہئے، مجھ پر یقین کرو. جدید پروڈکشن سرورز یا کلاؤڈ مشینوں پر میموری کی بڑی مقدار زیادہ پروسیسنگ میں تاخیر کو نہیں روکتی ہے۔ درحقیقت، میموری جتنی زیادہ ہوگی، اتنا ہی زیادہ امکان ہے کہ آپ یہ دیکھیں گے کہ GC کیسے کام کرتا ہے۔ نظریہ میں، عکاسی اس کے لیے ایک اضافی سرخ چیتھڑا ہے۔

تاہم، ہم سب IoC کنٹینرز اور ڈیٹ میپرز استعمال کرتے ہیں، جس کا آپریٹنگ اصول بھی عکاسی پر مبنی ہے، لیکن عام طور پر ان کی کارکردگی کے بارے میں کوئی سوال نہیں ہوتا ہے۔ نہیں، اس لیے نہیں کہ انحصار کا تعارف اور بیرونی محدود سیاق و سباق کے ماڈلز سے تجرید اتنا ضروری ہے کہ ہمیں کسی بھی صورت میں کارکردگی کو قربان کرنا پڑے۔ سب کچھ آسان ہے - یہ واقعی کارکردگی کو زیادہ متاثر نہیں کرتا ہے۔

حقیقت یہ ہے کہ عکاسی ٹیکنالوجی پر مبنی سب سے عام فریم ورک اس کے ساتھ زیادہ بہتر طریقے سے کام کرنے کے لیے ہر طرح کی چالیں استعمال کرتے ہیں۔ عام طور پر یہ ایک کیش ہے. عام طور پر یہ اظہار کے درخت سے مرتب کردہ اظہار اور مندوبین ہیں۔ وہی آٹو میپر ایک مسابقتی لغت کو برقرار رکھتا ہے جو ان فنکشنز کے ساتھ اقسام سے میل کھاتا ہے جو عکاسی کے بغیر ایک کو دوسرے میں تبدیل کر سکتے ہیں۔

یہ کیسے حاصل ہوتا ہے؟ بنیادی طور پر، یہ اس منطق سے مختلف نہیں ہے جسے پلیٹ فارم خود 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;
        }

یہاں ہم فوری طور پر پراپرٹیز کو نظرانداز کرتے ہیں اور سیٹ ویلیو کو براہ راست کال کرتے ہیں۔

وضاحت کے لیے اور ایک حوالہ کے طور پر، میں نے ایک سادہ طریقہ کو لاگو کیا جو ان کے باہمی تعلق کے جوڑوں کی اقدار کو براہ راست ہستی کے شعبوں میں لکھتا ہے۔ سابقہ ​​- دستی۔

اب بینچ مارک ڈاٹ نیٹ لیتے ہیں اور کارکردگی کا جائزہ لیتے ہیں۔ اور اچانک... (خراب کرنے والا - یہ صحیح نتیجہ نہیں ہے، تفصیلات ذیل میں ہیں)

عکاسی کو تیز کرنے کے بارے میں ناکام مضمون

ہم یہاں کیا دیکھتے ہیں؟ وہ طریقے جو فاتحانہ طور پر تیز سابقے کو برداشت کرتے ہیں وہ سست سابقے والے طریقوں کے مقابلے میں تقریباً تمام پاسوں میں سست ہوتے ہیں۔ یہ مختص اور کام کی رفتار دونوں کے لیے درست ہے۔ دوسری طرف، جہاں ممکن ہو، اس کے لیے LINQ طریقوں کا استعمال کرتے ہوئے نقشہ سازی کا ایک خوبصورت اور خوبصورت نفاذ، اس کے برعکس، پیداواری صلاحیت کو بہت کم کر دیتا ہے۔ فرق ترتیب کا ہے۔ پاسوں کی مختلف تعداد کے ساتھ رجحان تبدیل نہیں ہوتا ہے۔ فرق صرف پیمانے میں ہے۔ LINQ کے ساتھ یہ 4 - 200 گنا سست ہے، تقریباً اسی پیمانے پر زیادہ کچرا ہے۔

اپ ڈیٹ

مجھے اپنی آنکھوں پر یقین نہیں آیا، لیکن اس سے بھی اہم بات یہ ہے کہ ہمارے ساتھی کو میری آنکھوں یا میرے کوڈ پر یقین نہیں آیا۔ دمتری تیخونوف 0x1000000. میرے حل کو دو بار چیک کرنے کے بعد، اس نے شاندار طریقے سے ایک غلطی کو دریافت کیا اور اس کی نشاندہی کی جو ابتدائی سے حتمی تک، نفاذ میں متعدد تبدیلیوں کی وجہ سے مجھ سے چھوٹ گئی۔ Moq سیٹ اپ میں پائے جانے والے بگ کو ٹھیک کرنے کے بعد، تمام نتائج اپنی جگہ پر آ گئے۔ دوبارہ جانچ کے نتائج کے مطابق، مرکزی رجحان تبدیل نہیں ہوتا ہے - LINQ اب بھی کارکردگی کو عکاسی سے زیادہ متاثر کرتا ہے۔ تاہم، یہ اچھی بات ہے کہ ایکسپریشنز کو مرتب کرنے کا کام بے سود نہیں ہوا ہے، اور نتیجہ مختص اور عمل کے وقت دونوں میں نظر آتا ہے۔ پہلی لانچ، جب جامد فیلڈز کو شروع کیا جاتا ہے، قدرتی طور پر "تیز" طریقہ کے لیے سست ہوتا ہے، لیکن پھر صورتحال بدل جاتی ہے۔

دوبارہ امتحان کا نتیجہ یہ ہے:

عکاسی کو تیز کرنے کے بارے میں ناکام مضمون

نتیجہ: کسی انٹرپرائز میں عکاسی کا استعمال کرتے وقت، چالوں کا سہارا لینے کی کوئی خاص ضرورت نہیں ہے - LINQ پیداواری صلاحیت کو زیادہ کھا جائے گا۔ تاہم، زیادہ بوجھ والے طریقوں میں جن کے لیے اصلاح کی ضرورت ہوتی ہے، آپ انیشیلائزرز اور ڈیلیگیٹ کمپائلرز کی شکل میں عکاسی کو محفوظ کر سکتے ہیں، جو پھر "تیز" منطق فراہم کرے گا۔ اس طرح آپ عکاسی کی لچک اور درخواست کی رفتار دونوں کو برقرار رکھ سکتے ہیں۔

بینچ مارک کوڈ یہاں دستیاب ہے۔ کوئی بھی میرے الفاظ کو دو بار چیک کر سکتا ہے:
ہیبرا ریفلیکشن ٹیسٹ

PS: ٹیسٹوں میں کوڈ IoC کا استعمال کرتا ہے، اور بینچ مارکس میں یہ ایک واضح ساخت کا استعمال کرتا ہے۔ حقیقت یہ ہے کہ حتمی نفاذ میں میں نے ان تمام عوامل کو کاٹ دیا جو کارکردگی کو متاثر کر سکتے ہیں اور نتیجہ کو شور مچا سکتے ہیں۔

پی پی ایس: صارف کا شکریہ دمتری تیخونوف @0x1000000 Moq کو ترتیب دینے میں میری غلطی دریافت کرنے کے لیے، جس نے پہلی پیمائش کو متاثر کیا۔ اگر قارئین میں سے کسی کے پاس کافی کرم ہے تو براہ کرم اسے پسند کریں۔ آدمی رک گیا، آدمی نے پڑھا، آدمی نے دوبار چیک کیا اور غلطی کی نشاندہی کی۔ میرے خیال میں یہ احترام اور ہمدردی کے لائق ہے۔

PPPS: محتاط قاری کا شکریہ جو انداز اور ڈیزائن کی تہہ تک پہنچ گیا۔ میں یکسانیت اور سہولت کے لیے ہوں۔ پریزنٹیشن کی ڈپلومیسی بہت کچھ چھوڑ دیتی ہے، لیکن میں نے تنقید کو مدنظر رکھا۔ میں پروجیکٹائل کے لئے پوچھتا ہوں.

ماخذ: www.habr.com

نیا تبصرہ شامل کریں