سلام مجدد ...
(قولش را قبل از 24 ساعت داده بودم ولی خوب زودتر حاضر شد)
==============
----- کاهش عملیات Boxing و Unboxing در کد
عملیات boxing و unboxing یک عملیات داخلی فریم وروک است که برای برنامه نویسان C#.Net و VB.Net خودکار انجام میشود و اصلاً متوجه آن نمیشوند (ولی مثلاً برنامه نویسان VC++.Net مجبوراً صراحتاً دستور مربوطه را بنویسند)
دات نت زبانی کاملاً شی گرا است و تا انجا پیش رفته که Struct های ان نیز مطابق اصول شی گرایی هستند ...
تمام Struct های دات نت وراثتی هستند از System.ValueType و آن هم وراثتی است از System.Object
بدین ترتیب سلسه مراتب وراثتی برای Struct ها هم تامین شده که گاهاً میتواند باعث تعجب برنامه نویسان سایر زبانهای شی گرایی گردد.
این کار محاسن زیادی دارد و اجازه شی گرایی یکپارچه را در زبان برنامه نویسی میدهد و خیلی خوب است .
ولی اصول مدیریت داخلی حافظه برای Struct ها با Class ها بسیار بسیار فرق دارد و این در اصل سرچشمه تفاوت این دو ساختار است که من قصد و وقت تشریح ان را ندارم و تاثیری هم در کد ما ندارد.
نکته ای که مهم است ان جا است که دات نت چطور میتواند یک Struct را با یک سیستم مدیریت حافظه متفاوت در یک Object که Class است جای دهد؟؟؟
کنترل این عملیات به صورت خودکار بر عهده محیط CLR است و نام این عملیات box و unbox است.
عمل boxing چیزی شبیه این است ... (شبیه است ولی این طوری نیست!)
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
که طی آن یک struct (مثل value1) به یک class (مثل value2) تبدیل میشود.
عمل unboxing چیزی شبیه این است ... (شبیه است ولی این طوری نیست!)
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
که طی آن یک struct که داخل یک object است (مثل value2) به یک struct واقعی و آزاد (مثل value1) تبدیل میشود.
نکته مهم و قابل توجه انجا است که عملیات فوق بسیار بسیار پرسرعت و با بازدهی بالا است و اصلاً با کدهایی که دیدید برابر نیست و مستقیم و با سرعت بالا توسط هسته CLR انجام میشود و در هر اجرای یک کپی بسیار کوچک اطلاعات به حجم Struct هم رخ میدهد.
ولی با وجود پرسرعت بودن، انجام عمل فوق در یک حلقه عظیم میتوانید باعث افت سرعت شود،
مجدد تاکید میکنم که حلقه ای 100 بار انجام شود سرعت را 100 برابر کاهش میدهد و حلقه 1000 و 10000 و ... هم جای خود و در نهایت افزایش صفر مشکل ساز میشود.
کد عملی مثل این نمونه از boxing و unboxing است:
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
البته کد فوق به ذات مشکل خاص سرعتی ندارد ولی در حلقه ای که چند صفر ناقابل به ان اضافه کند ... !
ولی کد زیر اصلاً boxing و unboxing نیست : (گرچه ظاهرش یکسان است!)
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
چون کد اول Integer بود و Integer یک Struct است ولی String خودش یک Class است و نیازی به boxing ندارد.
نتیجتاً شما باید تا حد امکان از پاسکاری Struct ها به Object ها جلوگیری کنید.
=====
همانطور که اول گفتم شما باید مراقب کدنویسی داخلی ناپیدا توابع آماده هم باشید.
مثلا کد ساده زیر را در نظر بگیرید ...
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
یک کد ساده مختصر مفید و در اصل یک خطی برای مرتب کردن عناصر یک آرایه ... فقط یک خط ! (فقط تک خط آخری)
حالا اگر بگم تک خط کد فوق در بدترین شرایط باعث ...
- دو حلقه تو در تو مقایسه با حدود 130 هزار مقایسه ...
- 260 هزار box ...
- 260 هزار unbox ...
- جابه جایی و انتقال نزدیک 2MB اطلاعات در RAM میشود ...
حالا چه فکر میکنید؟؟؟
حالا فکر کنید قرار باشد کد فوق در متدی مثل Game.Update قرا داشته باشد و قرار باشد در هر ثانیه 60 باری اجرا شود !!!
برنامه شما در یک ثانیه 120MB اطلاعات را فقط به خاطر همین یک خط دستور در RAM جابه جا خواهد کرد!
حتماً باز هم میگید چرا برنامه کند است!!!
یادتان نرود اکثر کدهای برنامه نویسی شما همان تعداد خط کد ظاهری که شما تایپ میکنید نیستند.
(الگوریتم مرتب سازی یک چیز کلی و استاندارد در همه زبانها است و قرار نیست کاری در مریخ انجام شود، اگر دستور اجرا میکنید نباید انتظار داشته باشید که با جادو و دستور در یک آن در CPU اجرا شود، برای انجام عملیاتها یا شما باید الگوریتم را بنویسید یا کس دیگری قبلاً آن را نوشته و در هر دو صورت این الگوریتم هزینه ای برای اجرا دارد.)
==============
متاسفانه یا خوشبختانه بحث "سرعت و بازدهی کدهای مختلف" همچنان ادامه دارد !!!
(آمدیم یک پست در مورد این مطلب بزنیم ولی حالا ... !)
حداقل دو مطلب دیگر باید بیان شوند و وقت خالی ام فعلاً تمام شد.