PDA

View Full Version : بهینه سازی های وسواسی/نابخردانه



eshpilen
جمعه 18 آذر 1390, 13:59 عصر
فکر کردم این میتونه موضوع مفیدی باشه.
نظر به اینکه بنظر میرسه عدهء زیادی از افراد وسواس زیادی روی بهینه سازیهای جزیی دارن و گذشته از اتلاف وقت و انرژی خودشون، مخدوش شدن پارامترهای دیگر رو دست کم میگیرن، در اینجا نمونه هایی از بهینه سازیهایی رو که ممکن هستن اما نباید انجام بشن مطرح میکنم.
البته هرکس آزاده نظر خودش رو بیان و مخالفت کنه.

خب اولین مورد مثلا یه چیز ساده ای مثل اینه:

$lockdown_period=12*60*60; //in seconds
اینجا ما یک تنظیم در فایل پیکربندی برنامه داریم.
خب ما مقدارش رو میخواستیم 12 ساعت باشه و چون برحسب ثانیه بوده نوشتیم 12*60*60.
ما میتونیم اینجا یه بهینه سازی انجام بدیم و بجای 12*60*60 بنویسیم 43200.
این باعث میشه تا در هر بار اجرا PHP مجبور به انجام چند محاسبهء ضرب و مخلفاتش نباشه.
اما من فکر میکنم این پردازش و زمان اضافه اونقدر ناچیزه و از طرف دیگه نوشتن اعداد به اون صورت خوانایی بیشتری به کد میده که نباید این کار رو بکنیم.

نوشتن بصورت خوانا هم برای برنامه نویس موقع توسعه و تست و باگیابی کمک میکنه و هم بعدها برای کاربر برنامه از بروز یکسری اشتباهات جلوگیری میکنه.

یه مورد دیگه:

some_page.php:
include 'some_operation.php';
...

some_operation.php:
include 'some_operation_configs.php';
if(!some_config_var) return;
...

در این نمونهء فرضی که البته نمونهء واقعیش در پروژهء خودم هست، ما در یک صفحه یک صفحه/کد دیگری رو اینکلود کردیم و اون کد خودش یک فایل دیگر که حاوی تنظیمات برای عملیاتی که میخواد انجام بده هست رو اینکلود میکنه و اگر مقدار یکی از تنظیمات false بود، اجرا ادامه پیدا نمیکنه و اجرای برنامه بدون هیچ نتیجه ای از کد اینکلود شده به صفحهء اولیه باز میگردد.
در این روش درکل ما دو عملیات اینکلود داشتیم. چه کد مورد نظر اجرا بشه و چه عملیاتی اجرا نشه.

خب حالا ما میتونستیم کد رو اینطور بنویسیم:

some_page.php:
include 'some_operation_configs.php';
if(some_config_var) include 'some_operation.php';
...

some_operation.php:
...

یعنی تنظیمات رو در فایل اصلی اینکلود کنیم و بر اساس متغییر مربوطه تشخیص بدیم آیا عملیات باید اجرا بشه یا نه و اگر جواب مثبت بود فایل کد مربوط به عملیات رو اینکلود کنیم.
در این حالت اگر تنظیمات بگن که عملیات میتونه انجام بشه ما در کل دو عملیات اینکلود خواهیم داشت؛ یکی برای اینکلود کردن تنظیمات و دیگری برای اینکلود کردن کد عملیات مورد نظر. مثل مورد قبل.
اما اگر تنظیمات بگن که عملیات نباید انجام بشه، ما دیگه فایل محتوی کد عملیات رو اینکلود نمیکنیم و بنابراین تعداد اینکلودهای ما در این حالت یکی کمتر از روش قبلی خواهد بود.

خب ما میتونیم فرض کنیم که روش دوم بهینه تره. ولی آیا این کار تاثیر عملی مشهودی در اجرای برنامه خواهد داشت و آیا عوارضی نداره؟
کدام خواناتر هست؟
کدام از نظر توسعه و نگهداری برنامه بهتره؟
بنظرم اینکه موارد مربوط به یک عملیات همه درداخل یک فایل مجتمع شده باشن بهتره.
فرضا اگر نظیر این روش در 10 فایل وجود داشته باشه، وقتی تغییری در ساختار فایل تنظیمات بوجود میاد، مجبوریم تک تک اون 10 فایل رو پیدا کرده و اونها رو با تغییرات و ساختار جدید فایل تنظیمات تطبیق بدیم، اما وقتی دسترسی به تنظیمات فقط در فایل مربوط به فایل کد اون عملیات خاص وجود داشته باشه، اون فایل رو میشه براحتی پیدا و خیلی سریعتر و راحتتر و با احتمال خیلی کمتری برای خطاهای انسانی اصلاح کرد.

بازهم میشه مثالهای بیشتری آورد. و شما هم اگر موردی داشتید در تاپیک درج کنید.
منظورم از این بحث این بود که بهینه سازی هزاران نوع دارد، ولی بسیاری از بهینه سازیها درواقعیت به هیچ وجه تاثیر مشهود یا قابل توجهی نخواهند داشت یا پارامترهای دیگری رو مخدوش خواهند کرد که ارزش اون افزایش پرفورمنس رو نداره.

اینکه خیلی ها به بهینه سازی به شکل وسواسی توجه دارن و هرچقدر هم در اون مهارت داشته باشن، یک نقطهء قوت نیست. این نشان دهندهء یک دیده محدود و عدم تفکر منطقی واقعگرایانه و عدم توانایی در برقراری تعادل میان تمام پارامترهای مختلف برنامه و نیازها و شرایط واقعی هست.
قبلا هم گفتم این بیشتر شبیه یک بیماری هست.
واقعا بهینه سازی در این حد وسواسی و در خیلی موارد قبل از اینکه نیاز عملی بهش دیده بشه، هیچ ارزشی نداره.
اینهمه مبحث و اینهمه نقص و موارد بهبود ممکن برای برنامه هست ولی یک عده همش چسبیدن به بهینه سازی. چرا؟
اصلا بهینه سازی چیزی نیست که اینقدر بحث و ارزش داشته باشه. خصوصا امروزه که قدرت و منابع رایانه ها خیلی خیلی بیشتر از قدیم هست و زبانها و امکانات سطح بالای زیادی بوجود آمدن برای همین که سطح برنامه نویسی رو بالا ببرن و برنامه نویس بیشتر روی منطق و الگوریتم و امنیت برنامه تمرکز بکنه.

وقتی یک نفر برنامه و کدی نوشته باید اول به منطق و خوانایی و امنیت اون نگاه کنیم و اگر درسته تاییدش کنیم. و اگر فردا آمد گفت با پرفورمنس مشکل دارم اونوقت باید بهینه سازیهایی رو بهش پیشنهاد کرد. یا اگر خودمون در اون مورد تجربهء عملی داریم که با شرایط طرف هم احتمالا چنان تجربه ای باارتباط خواهد بود. یا درمورد بهینه سازیهایی که میتونن واقعا بزرگ باشن.
اما الان قضیه خیلی وسواسی و حتی معکوس هست.
تا یه نفر برنامه ای مینویسه و کدی میذاره همه میان از جزء به جزء سینتاکسش ایراد میگیرن و کلی بهینه سازی در حد میکروثانیه ارائه میکنن که به احتمال 99% در عمل هیچوقت هیچکس متوجه تاثیر اونا نخواهد شد، اما خوانایی و دقت و کمال الگوریتم و استحکام امنیت برنامه فدا میشه یا اینطور بگیم که اصلا کمتر کسی دانش و مهارتی به همون نسبت در این حیطه داره و متوجه خیلی از مسائل در این زمینه نمیشن.

اینکه ما از بهینه نبودن سینتاکس ایراد بگیریم واقعا کار سختی نیست و هنری هم محسوب نمیشه. میبینید که این کار رو بیشتر افراد بعد از کمی مطالعه و تجربه میتونن انجام بدن. درمورد بهینه سازی اگر به واقعیت و تاثیر و ارزش عملی اونها توجهی نداشته باشیم و به هزینهء اونها بر پارامترهای دیگر توجهی نکنیم، میشه کلی نوشت و صدها مورد رو مطرح کرد، میشه از میان چند روش و چند تابع قابل استفاده برای یک عملیات همه رو آنالیز و تست کرد و سر میکروثانیه ها و میلی ثانیه ها چک و چونه زد، ولی واقعا در این کار چه توجیه و هنری هست؟ اینقدر مباحث اساسی و مهمتر و موثرتر در زمینه های مختلف هست و اینقدر چیزهای جالب که صرف وقت و انرژی روی چنین کارهایی جز یک بازی کودکانه چیز دیگری بنظر نمیرسه.
و آدم اگر یک روزی به مشکل پرفورمنسی برخورد بکنه که واقعا با چنین مواردی در ارتباط باشه و بشه با چنین تغییرات جزیی حلش کرد، فکر نمیکنم کشف و حل اون چندان دشوار باشه و نیاز به سواد زیاد و آگاهی قبلی در این مورد داشته باشه. هر برنامه نویس حرفه ای میتونه جای مشکل پرفورمنس رو پیدا بکنه، و معمولا bottleneck های متعدد بسیار بزرگتری در جاهای دیگری وجود دارن که مشکل از اونها ناشی و با حل اونها برطرف میشه.

eshpilen
جمعه 18 آذر 1390, 14:00 عصر
درستش هم همینه! کامنت رو هم برای همین گذاشتن. شما نباید بخاطر خوانایی از قدرت/سرعت برنامه بکاهی.
برای خوانایی هم باید اینطوری بنویسی(که معمولاً هم اینطوری عمل می کنند):


$lockdown_period= 43200; # | 12 * 60 * 60


البته اگر از روش دوم استفاده کردیم کامنت هم بذاریم خوبه و بهتر میشه، ولی بازهم به خوانایی و راحتی و سرعت روش اول نیست و احتمال خطای انسانی درش بیشتره.
روش اول self document هست و میدونی که این با کامنتی که ما خودمون اضافه کنیم فرق میکنه.
من موقع توسعه و تست برنامه یا بعدا موقع کانفیگ روش اول رو راحتتر و سریعتر میبینم و احتمال خطای انسانی هم درش کمتره. و فکر میکنم این بقدر کافی واضح باشه.
اون کامنت که شما خودت هربار باید دستی اضافه کنی و محاسباتی که انجام میدی و بعد نتیجه رو درج میکنی و اینکه ممکنه این وسط اشتباه و عدم هماهنگی پیش بیاد همهء اینا طبیعی هست که هم کار و دقت بیشتری میبره و هم احتمال خطای انسانی درش بیشتره.
در روش شما ما هربار باید خودمون محاسبه کنیم، نتایج رو درج کنیم، و کامنت رو هم آپدیت کنیم. این فرایند هم کار بیشتری میبره و هم احتمال خطای انسانی در مراحل مختلف بیشتری که باید بصورت دستی انجام بشن و ازشون غفلت نکنیم بیشتره.
من موقع توسعه و تست و باگیابی میخوام همه چیز واضح باشه و کمترین احتمال خطا رو داشته باشه. نه اینکه وقتی دارم با کلی زحمت و دقت و کلی پارامتر و احتمال خطای انسانی دیگه تست میکنم، مطمئن نباشم و شک کنم آیا کامنت رو آپدیت کرده بودم یا نه، آیا در جریان محاسبه و انتقال عدد خطایی پیش آمده یا نه. و شاید حتی حضور ذهن نسبت به این مطلب نداشته باشم که کار از اینهم بدتر بشه و در یک حداقل وقت و انرژی تلف میشه و در حداکثر تنظیمات برنامه اشتباه تعیین میشه و حتی باعث ایجاد باگهای مختلف امنیتی و غیرامنیتی در برنامه میشه.

بنابراین هرچه برنامه واضح تر و مراحل خودکارتر باشن و دخالت و نیاز به دقت انسان کمتر باشه بهتره.

میتونم بگم به درجهء کمتری برای استفاده از برنامه و پیکربندی اون در آینده هم این روش رو باز ترجیح میدم به علل کم و بیش مشابهی.
تنبلی یا غفلت برنامه نویس و مدیر سیستم و غیره امر نامعمول و کم احتمالی هم نیست. بنده بارها دیدم که کسی حتی جایی که لازمه کامنت نمیذاره یا کامنت مشکل داره و حتی اشتباه و گمراه کننده بوده.



در 1-2 فایل یا پروژه کوچیک خیر، تاثیری نداره... ولی وقتی پروژه های بزرگ/سنگین می نویسی اونجا خودشو نشون میده!
خب دیگه اگر در چنان پروژه ای شما واقعا به مشکل برخوردید که این بهینه سازیهای جزیی میتونست حلش کنه خب انجام میدید. مشکلی هست؟ از الان باید در هر برنامه ای پیاده کنید؟
ضمنا فراموش نکنید در پروژه های بزرگ فقط پارامتر پرفورمنس نیست که مهمتر میشه. حتی میتونم بگم نقش خوانایی و سادگی و حجم کد با سرعت بیشتری و در موارد بیشتری برجسته تر میشه.

در مورد خوانایی و نگهداری هم در این مثال فرق زیادی ندارند.
فرقش رو گفتم. چرا تفاوت کمی هست؟
اینکه چیزهای مرتبط در یک جا باشن و برای تغییر و اصلاح کار و کدنویسی کمتری نیاز داشته باشید و احتمال خطای انسانی کمتر بشه مسئلهء کوچکی نیست.
برنامهء خود من اینقدر فایلهاش بزرگ و حجیم و پیچیده شده بود که دیدم اصلا داره بهم فشار میاد تا میخوام یه منطق و کدی رو یک جا پیدا کنم کلی وقت و انرژی صرف میکنم و احتمال اشتباه هم واقعا زیاد میشه. بخاطر همین کدها رو بازهم کاهش دادم و در فایلهای بیشتری توزیع کردم (که طبیعتا تعداد اینکلودها رو افزایش میده).


اگر قرار بود همه اینجوری فکر کنن، هیچوقت PHP Python Linux ... به اینجا نمی رسیدن!
برنامه ای که خودش سرویس دهنده هست فرق میکنه. برنامه ای که بحث برنامه نویسی سیستمی داره فرق میکنه. مطمئن باش اونا هم در خیلی موارد میتونستن یکسری بهینه سازیهای جزیی انجام بدن اما انجام ندادن و فقط اونایی رو که واقعا مفید یا لازم بودن انجام دادن. تازه اگر کار بیشتری هم کردن طبیعتا این در طول سالها تجربه و بازنگری و بعد از تسلط و اطمینان بالایی نسبت به پارامترهای دیگر و تثبیت اونها انجام شده و این خیلی فرق میکنه با اینکه ما از ابتدا بخوایم یک باره چنین سطحی از بهینه سازی رو روی هر پروژه ای انجام بدیم.
ضمنا شما یجوری صحبت میکنی انگار همهء کدها و بهینه سازیها و عدم بهینه سازیها رو خودت دیدی و اطلاع و اطمینان داری. یعنی واقعا 100% کدهای PHP رو به دقت خوندی و فهمیدی؟ یعنی نه فقط هستهء مفسر و زبان، بلکه تمام اجزای یک پکیج استاندارد رو.
ضمنا حالا ما باید نظر شما رو باور بکنیم و معیار قرار بدیم؟ سند میشه برای ما؟


میشدن همون آشغالهایی که مایکروسافت میده بیرون.
اینم باز یه ادعای بدون سند دیگه.
یک حرف کلی و مبهم.
منظورتون ASP.NET هست؟
چرا بنظرت آشغاله؟
بنظر خیلی ها بقدر کافی موفق بوده و مزایا و کاربران خودش رو داره.
خیلی سایتها هم دارن باهاش نوشته میشن و کار میکنن.


شما سورسشونو نگاه کن، میبینی جای کوچیک ترین تغییر/بهینه سازی نداره(خیلی خیلی خیلی باید روش فکر کنی تا یه چیزی ازش در بیاری)
اینقدر که به جزییات و کوچیکترین مسایل هم اهمیت دادن
همونطور که گفتم برنامهء سرویس دهنده و سیستمی یه چیز دیگه هست.
وگرنه چرا شما خودت از C استفاده نمیکنی و اونطوری خیلی جزیی تر میتونی بهینه سازی هم بکنی.
من این سوال رو تاحالا بارها پرسیدم، اما جالب اینکه هیچکس جواب قانع کننده ای بهش نمیده.
ضمنا اساسا شک دارم اونطور که شما میگی بهینه سازی های جزیی در تمام بخشها باشه. شما هم که همهء سورس رو نخوندی. طبیعتا جاهایی که bottleneck یا هسته و مرکزی هستن بهینه سازی مهمتره و بعضی جاها حتی از اسمبلی استفاده کنن. همینکه میگم از اسمبلی، بنظرت چرا همهء کد رو با اسمبلی نمینویسن؟ مگر اسمبلی در جاهای دیگر سرعت رو بالا نمیبره؟
پس هرچیزی جای خودش رو داره و نمیشه یا درواقع صرف نمیکنه هرنوع بهینه سازی رو در هرجایی انجام داد.

همین سیستم عامل، چه ویندوز و چه لینوکس، از زبانهای مختلفی در سطح های مختلفی درش استفاده میشه و در سطوح مختلفی بهینه سازی میکنن. یک جاهای محدودی با اسمبلی هم مینویسن، و بیشتر بقیش با سی و سی++، و یکسری یوتیلیتی ها و برنامه های جانبی رو با زبانهای سطح بالاتر و حتی اسکریپتی مینویسن. تازه این سیستم عاملی هست که اینقدر بزرگ و پیچیده و سنگین هست و میخواد به برنامه های دیگر اعم از سرویس دهنده و اپلیکیشن سرویس بده و Base اونا باشه.