منطق صحیح بهینه سازی در برنامه نویسی

بهینه سازی فرایند اجرای موثرتر برنامهء کاربردی شماست. شما میتوانید برای چیزهای زیادی بهینه سازی کنید – سرعت، مصرف حافظه، مصرف دیسک، غیره. اما ما در اینجا بر روی بهینه سازی سرعت معطوف هستیم.

– چه وقت بهینه سازی کنیم؟

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

مادامیکه شما برنامه تان را توسعه میدهید، به داشتن اولویت های زیر نیاز دارید:

- همه چیز مستند شده باشد
- همه چیز همانطور که مستند شده است کار کند
- کد در یک شکل ماجولار و براحتی قابل تغییر نوشته شده باشد

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

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

بنابراین، وقت بهینه کردن در انتهای توسعه است، وقتیکه شما مطمئن شده اید که کد صحیح شما عملا مشکلات کارایی (performance) دارد.

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

———————————-

م: تنگه (bottleneck) به بخشهایی از برنامه یا هر سیستمی میگویند که حاصل تمام بخشهای دیگر یا بازدهی نهایی سیستم تحت تاثیر آنست (بنوعی مجبور به گذر از آن است، و غیره) و بنابراین محدودیت اصلی کارایی برنامه در این بخش از برنامه قرار دارد که در موارد مشکل باعث افت کلی بازدهی سیستم به زیر حد مورد نیاز یا حد قابل تحمل میشود، باوجود اینکه در بخشهای دیگر برنامه/سیستم چنین محدودیتی وجود نداشته باشد یا حتی ظرفیت بالاتر از حد نیاز وجود داشته باشد.

======================

منبع:

Programming from the Ground Up
Jonathan Bartlett
Edited by
Dominick Bruno, Jr.
http://download.savannah.gnu.org/release…oksize.pdf

Chapter 12. Optimization

=====================

– بزرگترین بهبود در پرفورمنس در میان تمام آنها وقتی است که یک سیستم از حالت عدم کارکرد به کارکرد میرود

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

گهگاه بخشهایی از یک برنامه وجود خواهند داشت که پرفورمنس اهمیت دارد، اما شما احتمالا قادر نخواهید بود پیشبینی کنید در کجا مسئلهء پرفورمنس رخ خواهد داد. اگر شما تلاش کنید پرفورمنس یک اپلیکیشن را در طول ساخت اولیه بهینه کنید شما پیچیدگی ای را اضافه خواهید کرد که به تحویل بموقع و کیفیت اپلیکیشن ضربه خواهد زد و احتمالا هیچ کمکی به پرفورمنس نخواهد کرد؛ درواقع، آن میتواند عملا پرفورمنس را کاهش دهد (الگوریتم های سریعتر معمولا فاکتورهای ثابت بزرگتری دارند که به معنای آنست که آنها در مقیاس کوچک کندتر هستند و فقط در مقیاس بزرگ کاراتر میشوند). من دریافته ام که در بیشتر شرایط ساده ترین کد همچنین سریعترین کد نیز هست. بنابراین، دربارهء پرفورمنس تا زمانیکه برنامه درحال اجرا نباشد نگران نباشید؛ اگر آن بقدر کافی سریع نبود، سپس بدقت ارزیابی کرده و دریابید تنگه های پرفورمنس (performance bottlenecks) در کجا قرار دارند (محتملا آنها در جاهایی هستند که شما حدس نمیزدید). تنها آن مکانهایی را تنظیم کنید که شما ارزیابی کرده اید مشکلی وجود دارد.

==========================

منبع: http://www.stanford.edu/~ouster/cgi-bin/sayings.php

==========================

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

- سطح طراحی
- سطح کد
- سطح کامپایل
- سطح اسمبلی
- سطح زمان اجرا

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

بهینه سازی ممکن است شامل یافتن یک تنگه (bottleneck) باشد؛ بخشی از کد که مصرف کنندهء اصلی منابع مورد نیاز است. اغلب قاعدهء Pareto اعمال میشود: 20 درصد از کد مسئول 80 درصد از نتایج است.

در علم رایانه، قاعدهء Pareto میتواند با مشاهدهء اینکه 80 درصد از منابع معمولا توسط 20 درصد از عملیات استفاده میشوند، اعمال شود. در مهندسی نرم افزار، اینکه 90 درصد از زمان اجرای یک برنامه صرف اجرای 10 درصد از کد میشود (شناخته شده بعنوان قانون 90/10) اغلب تخمین بهتری است.

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

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

چه وقت بهینه کنیم؟

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

Donald Knuth دو عبارت زیر را درمورد بهینه سازی بیان کرد:

1) ما باید افزایش کارایی های جزیی را فراموش کنیم، در 97 درصد اوقات: بهینه سازی زودهنگام ریشهء تمام چیزهای بد است.

2) در قواعد جا افتادهء مهندسی یک بهبود 12 درصدی که به سادگی بدست بیاید، هرگز ناچیز شمرده نمیشود و من باور دارم که دیدگاه یکسانی باید در مهندسی نرم افزار حاکم باشد.

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

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

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

بنابراین یک مشی بهتر آن است که ابتدا طراحی کنیم، سپس بر اساس طراحی کدنویسی کنیم، و سپس کد حاصل را برای دیدن آنکه کدام بخشها باید بهینه شوند پروفایل/بنچمارک کنیم. یک طراحی ساده و زیبا اغلب برای بهینه سازی در این مرحله ساده تر است و پروفایل کردن میتواند مسائل پرفورمنس غیرمنتظره ای را فاش کند که با بهینه سازی زودهنگام برطرف نمیشدند.

در عمل، اغلب لازم است که اهداف پرفورمنس موقعی که نرم افزار نخست طراحی میشود در ذهن باشند، اما برنامه نویس اهداف طراحی و بهینه سازی را متعادل میکند.

——————–

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

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

——————-

نقل قولها:

گناهان کامپیوتری بیشتر بنام کارایی انجام میشوند (بدون آنکه لزوما به آن دست یابند) تا هر علت دیگری – منجمله حماقت کورکورانه. W.A. Wulf

ما باید کارایی های جزیی را فراموش کنیم، 97 درصد اوقات: بهینه سازی زودهنگام ریشهء تمام بدیهاست. اما ما نباید از فرصتهای خود در آن 3 درصد بحرانی صرفنظر کنیم. یک برنامه نویس خوب بوسیله چنان استدلالی دچار از خود راضی بودن نخواهد شد، او برای با دقت نگاه کردن به کد بحرانی عاقل خواهد بود؛ اما فقط پس از آنکه آن کد شناسایی شده است. Donald Knuth

تنگه ها در نقاط غافلگیرکننده ای رخ میدهند، پس تلاش نکنید آنها را پیشبینی کرده و یک هک سرعت در آنجا بگذارید، تا وقتی که ثابت کرده باشید آنجا جایی است که تنگه وجود دارد. Rob Pike

نخستین قاعدهء بهینه سازی برنامه: آنرا انجام ندهید. دومین قاعدهء بهینه سازی برنامه (فقط برای متخصصان): هنوز آنرا انجام ندهید. Michael A. Jackson

===============================================

منبع: بخشهای گزیده ای از http://en.wikipedia.org/wiki/Program_optimization

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>