نود و هفت چیزی که هر برنامه‌نویسی باید بداند: استفادهٔ درست از الگوریتم‌ها و دیتا استراکچرها


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

شرکت‌ نرم‌افزاری هم چند متخصص و تحلیلگر به شعبه‌ٔ مرکزی بانک مذکور فرستاد تا ریشهٔ مشکل را بیابند و چیزی نگذشت که دریافتند کدی توسط مدیر آی‌تی خود بانک روی سیستم نوشته شده بود که در بک‌گراند به صورت کامندلاینی اجرا می‌شد و تقریباً می‌شود گفت تمام پتانسیل CPU را استفاده می‌کرد:

for (i=0; i < strlen(s); ++i) {
if (... s[i] ...) ...
}

در واقع، در تحلیل کد فوق بایستی گفت که استرینگ s به طور میانگین حاوی هزاران کاراکتر بود و با ایجاد یکسری تغییر در کد، مشکل بانک به سادگی حل شد! به عبارت دیگر، فراخوانی متد ()strlen تک‌تک هزاران کاراکتر موجود در s را شامل می‌شد و این در حالی بود که اگر دولوپر این کد از قبل طول این استرینگ را مشخص می‌کرد، می‌توانست هزاران فراخوانی متد ()strlen و بالتبع میلیون‌ها اجرای لوپ را از سیستم حذف کند. کد فوق به صورت زیر به سادگی بهینه شد:

n = strlen(s);
for (i=0; i < n; ++i) {
if (... s[i] ...) ...
}

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

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

مسلماً در چنین شرایطی استفاده از دیتا استراکچر مناسب نتیجهٔ بسیار مطلوبی برایمان در بر خواهد شد. به عبارت دیگر، استفاده از جدولی که در آن داده‌های مرتبط با کاربران به صورت اصطلاحاً Serialized شده ذخیره گردد اصلاً بهینه نبوده بلکه در عوض نیاز به جدولی خواهیم داشت که ستون‌های مورد نیاز به خوبی در آن ایندکس شده باشند.

برخی بر این باروند که مهم‌ترین استراتژی در کدنویسی استفاده از کدهایی است که قبلاً نوشته شده است اما نکتهٔ مهم اینجا است که ما به عنوان یک دولوپر حرفه‌ای می‌بایست بدانیم که چه چیزی را چگونه و در چه زمانی استفاده کنیم (شاید مدیر آی‌تی بانک مذکور کد فوق را از داخل پروژه‌ای دیگر برداشته باشد که قرار بوده صرفاً تعداد کاراکتر معدودی به فانکشن ()strlen پاس داده شود که مسلماً در چنین شرایطی کد به خوبی کار می‌کرده است).



بهزاد مرادی

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
محسن
محسن
۱۳۹۷/۰۱/۲۰
استراتژی «اول کدی بنویس که کار کند، سپس آن را بهینه کن» خیلی خوب هست و یک اصل دیگه هم اینه که هر برنامه بزرگی اول یک برنامه کوچیکی بوده که کار می کرده، و ارایه نسخه های اولیه محصول و اینکه برای ساخت ماشین میشه اول اسکیت برد ساخت بعد اسکوتر بعد دوچرخه بعد موتور و بعد ماشین
ولی یک نکته خیلی مهم درباره این مباحث این هست که بسیاری از افراد بخش "اول کدی بنویس که کار کند" را به خوبی انجام می دن و بخش "سپس آن را بهینه کن" رو کلا فراموش می کنن، این موضوع اغلب به دلیل نداشتن زمان کافی، موارد مالی و... اتفاق میفیته و اون موضوع در بهترین حالت اگر تاثیر منفی در برنامه نداشته باشه و به نوعی اجباری برای بهینه کردنش نباشه دیگه درست نمیشه

این موضوع در کیفیت کارکرد و زمان اجرا و پاسخگویی برنامه ها خیلی با اهمیت هست (همون موارد مربوط به مرتبه و پیچیدگی زمانی در اجرای الگوریتم ها و بیگ اُ و...)
و درسته که خیلی از رفرنس ها اشاره می کنن که از نسخه های حداقلی شروع کنید ولی تعهد و انضباط بعدش هم خیلی مهم هست
Insight
Insight
۱۳۹۷/۰۱/۱۸
ساختمان داده و طراحی الگوریتم معمولا به عنوان مباحث پیشرفته در برنامه نویسی مطرح میشن اما اهمیت توجه به این دو باید از همون آغاز کار یک برنامه نویس گوشزد بشه و در کنار یادگیری مبانی با این مسائل هم درگیر شد.
استفاده از الگوریتم های بهینه و ساختمان داده های مناسب میتونه متضمن کیفیت یک سورس کد باشه.
مشابهت سازی این دو مقوله با دنیای واقعی هم کار ساده ای ست.
مثلا روشی که معمولا انسان ها برای مرتب کردن تعدادی کارت شماره دار انجام میدن همون مرتب‌سازی درجی یا Insertion Sort هست و یا نحوه ی نشستن روی صندلی عقب یک تاکسی ما رو یاد ساختمان داده پشته یا Stack میندازه (به شرط بسته موندن درب سمت راننده)