برای هرکسی که مدت زیادی با کامپیوترها کار کرده باشه واضحه برنامهها عموما در گذر زمان کندتر و حجیمتر از قبل شدن. اشخاص زیادی متوجه این موضوع هستن و دربارش نوشتن و من هم میخوام دربارش بنویسم؛ چون این مسئله برای من اهمیت زیادی داره و تقریبا همیشه، یکی از معیارهایی هست که موقع نوشتن کد اونو درنظر میگیرم.
درباره بهینهسازی کد، ترس عجیبی در بین مهندسان نرمافزار شکل گرفته. تاحدودی منطقی هم هست؛ به این دلایل:
- معمولا کسی که زودتر وارد بازار میشه موفقتره. بنابراین یک عجلهای در ذهن دستاندرکاران هست که هرچه سریعتر محصولشون وارد بازار بشه و کاربر بگیره. برای همین، سرعت ساخته شدن محصول از سرعت اجرا شدنش مهمتره.
- بیشتر اوقات، سرعت نرمافزار با انعطافپذیریش رابطه عکس داره. ما میتونیم یک کار مشخصی رو سریعتر انجام بدیم یا کدهایی بنویسیم که میتونن کارهای مختلفی رو، کندتر انجام بدن. و دیدگاه اینه که ویژگیها و امکانات بیشتر مهمتر از روون و سریعتر بودنه.
- نوشتن کدها با هدف سرعت، میتونه باعث استفاده از روشهایی عجیب و غریب و ناخوانا شدن کدها بشه که درآینده درک اونارو مشکل میکنه.
- حکایت دستمال بستن به سری که درد نمیکنه. بیشتر مواقع سختافزار به قدری سریع هست که میتونه بیکفایتی نرمافزار در بحث سرعت رو جبران کنه. بنابراین مد شده که میگن تا وقتی کندی برنامت غیرقابل تحمل نشده؛ سعی نکن سریعترش کنی.
من همه دلایل بالا رو درک میکنم؛ و معتقدم که همچنان بهانه خوبی برای توجیه افتضاحی که در صنعت نرمافزار به بار اومده نیستن. این دلایل، میتونن به ما بگن چرا نرمافزارهای ما با سرعت نور کار نمیکنن؛ اما نمیتونن توضیح بدن که چرا رفتهرفته داریم کندتر و کندتر میشیم درحالی که سختافزاری به مراتب قویتر در اختیارمون هست؟ سختافزار امروز صدها برابر از گذشته سریعتره. کدهای ما چقدر باید بدتر شده باشن که بازهم کند بنظر بیان؟ آیا این کندی چندهزاربرابری، باعث کیفیت بالاتر نرمافزارهای امروزی شده؟ فکر نکنم. فقط ردیابی و تبلیغات بیشتر داریم درکنار امکانات کمتر و قفل کردن کاربر.
بیشتر اوقات کسانی که میگن سرعت کدها مهم نیست؛ معتقدن که خوانایی کد و عملکرد صحیحش خیلی مهمتره. اما همین دوستان کدهای ناخوانایی مینویسن که علاوه بر اینکه کند و سنگین هستن؛ درست هم کار نمیکنن! و در چنین دنیایی، سیستمی که درست کار میکنه و سریع هم هست؛ خیلی به چشم میاد.
معمولا زمانی که نرمافزارهای خودم رو به دیگران نشون میدم؛ اولین واکنش اونها اینه که میگن چه روون کار میکنه! این اتفاق درحالی میفته که شاید تلاش مستقیمی برای سریعتر شدن اون سیستم انجام ندادم؛ بلکه محصولات دیگران به قدری کند و سنگین شدن که صرفا با رعایت حداقلها میتونم استثنایی جلوه کنم.
بعضی اوقات یا باید از اول به فکر باشیم و چیزی رو در طراحیمون لحاظ کنیم؛ و یا بعدا نمیشه کاریش کرد. دیدگاه من اینه که هروقت تونستیم کشمش رو به داخل کیک پخته شده اضافه کنیم؛ سرعت رو هم میشه به نرمافزار وصله پینه شده اضافه کرد. بنابراین بنظر من یا از ابتدا باید فاکتور سرعت مدنظر باشه؛ یا محصول ما کند از آب در خواهد اومد.
در این شرایط اما، دیدگاهم اینه که نیازی نیست کدهایی با هدف سرعت بنویسیم؛ بلکه کافیه چیزهای غیرضروری رو حذف کنیم. کندتر نکردن، مهمتر از بهینه کردنه.
وقتی میخوایم سیستمی رو با یک معیار مشخص مثل بررسی کنیم؛ چهار رویکرد کلی میتونن وجود داشته باشن:
ابتکار و بهبود تخصصی: در این حالت اون معیار برای ما خیلی مهم هست؛ و ما با تکیه بر تخصصمون راهحلی نوین یا کمتر شناخته شده پیدا میکنیم که باعث میشه سیستم ما نمره بهتری از نظر اون معیار بگیره و اونو تبدیل به یه امتیاز رقابتی کنه. مثلا اگه موتور بسازیم و سروصدای کمتر هدف ما باشه؛ با مطالعه عمیق محصولمون و بررسی راهحلهای مختلف درنهایت روشی غیرمتداول اما عاقلانه پیدا میکنیم که آلودگی صوتی موتورمون به نصف کاهش پیدا کنه.
پیروی از قواعد شناخته شده: در این حالت، اون معیار اساس کار ما نیست. اما راهحلهایی از قبل توسط دیگران کشف شدن و به شکل استاندارد دراومدن؛ و ما تشخیص میدیم این راهحلها به کار ما میان. پس کافیه از اونها پیروی کنیم تا امتیاز قابل قبولی بگیریم. اینجا چندان نیاز به ابتکار و آزمون و خطا نیست و صرفا کار رو مطابق استاندارد عمومیش پیش میبریم. مثلا از نظر رابط کاربری، تلاش میکنیم کنتراست و سادگی رو رعایت و از خط مشیهای شناخته شده پیروی کنیم. نتیجه یک رابط کاربری معمولی میشه که شاید خارق العاده بنظر نیاد اما کار راه بنداز و اوکی خواهد بود. میتونیم یک نرمافزار مطابق استانداردهای عادی بسازیم؛ و در طراحیش حواسمون باشه که به دلایل واهی سرعت رو از دست ندیم. نتیجه میشه یه نرمافزار که در حد قابل قبولی سرعت عمل داره. البته در دنیایی که کمتر کسی از این استانداردها پیروی میکنه؛ نرمافزار ما خیلی سریع و بهینه بنظر خواهد رسید. و من معتقدم باید از همین فلسفه پیروی کرد.
اشتباه در تشخیص وزن، تلاش بدون نتیجه: در این حالت اون معیار برای ما مهم هست؛ اما بدون اینکه خودمون بررسی کاملی کرده باشیم؛ حرف دیگران رو قبول میکنیم؛ یا با تکیه بر حدس و گمان شخصی خودمون فکر میکنیم که انجام فلان کار باعث بهبود اوضاع خواهد شد. وقت و زمان زیادی هم صرف انجام اون کار میکنیم؛ غافل از اینکه هیچ آوردهای نخواهد داشت. مثلا فکر میکنیم با دراز و نشست رفتن چربی شکممون آب خواهد شد؛ درحالی که از یک طرف این حرکت ورزشی در عین دشوار بودن کالری زیادی نمیسوزونه و از اونطرف آب کردن چربی در یک ناحیه خاص از بدن ممکن نیست. نتیجه این میشه که چربی شکمی کاهش پیدا نمیکنه اما شاید عضلات شکمی قویتری بدست بیاریم که خب هدف ما نبود. در حوزه نرمافزار ممکنه یه کدهایی رو بهینهسازی کنیم که اصلا کندی نرمافزار ما تقصیر اونا نبوده؛ یا کدهامونو طور خاصی بنویسیم به این خاطر که یه عده بهمون گفتن اینطوری سریعتره درحالی که اصلا اینطور نیست. درگیر شدن با micro-optimization به جای تمرکز بر ساختار کلی نرمافزار مثالی برای این دسته هست؛ که شاید کدی که کلا یک بار قرار هست اجرا بشه و ده میلی ثانیه زمان ببره رو بشینیم و بهینه کنیم درحالی که قسمتهای اصلی سیستم کند و سنگین کار میکنن.
بیکفایتی و به فنا دادن: در این حالت، سوای از اینکه اون معیار برای ما مهم بوده یا نه، کارهایی انجام میدیم که بدون یک دلیل محکمه پسند، سیستم رو بدتر از قبل میکنن. یعنی اشتباه میکنیم و برخلاف حالت قبلی که تلاش بیثمر داشتیم؛ اینبار در جهت عکس حرکت میکنیم و نتیجه منفی میگیریم. مثلا نرم افزاری میسازیم که هیچ دلیلی نداشت کند و سنگین باشه. اما هست. این افتضاح ممکنه نتیجه یک تلاش عمدی ناموفق برای بهبود اوضاع باشه یا نتیجه یک سهلانگاری غیرعمدی. ما میتونیم برنامه نویسی باشیم که از روی تنبلی یا عجله، کوهی از کدهای بیکیفیت میریزه تو نرمافزارش. همه چیز رو میخواد در سریعترین زمان ممکن وصله پینه بزنه تا پولو بگیره و بره سراغ کار بعدی. شاید با این تفکر که کندی نرمافزار رو بعدا میشه حل کرد یا شاید با این دیدگاه که کیفیت کد هیچ اهمیتی نداره. کدهای این مهندس ما، هم باگ داره، هم کنده، هم ناخواناست هم تست نداره و خلاصه از هر نظر به فناست. سرعت و کیفیت نرمافزار فدای بیکفایتی و زیادهخواهی برنامهنویس شده.
بنظر من یه متخصص باید در کارش از حالتهای سوم و چهارم به دور باشه. یعنی سیستمش هیچجایی بدون دلیل محکمه پسند لنگ نزنه. دلیل محکمه پسند یعنی اگر هم محصولش از یک نظر کم بیاره؛ اون کم آوردن یه فداکاری برای درخشیدن در بعد دیگهای باشه؛ که مشکلی نداره. اما در حالت کلی، پیشفرضمون اینه که متخصص ما حد استانداردی از کیفیت رو براساس معیارهای مختلف در نظر بگیره و یک راهحل متعادل و قابل قبول ارائه کنه.
قرار نیست همیشه بهینهسازی تخصصی و ویژهای برای نرم افزارهامون انجام بدیم و خودمون رو اذیت بدیم. همینکه حواسمون باشه بی دلیل فاکتور سرعت رو از دست ندیم؛ خیلی وقتها بیشتر از نیاز کفایت میکنه. درواقع، بهینهسازی نیاز نیست؛ فقط باید حواسمون باشه که کندسازی نکنیم و اگر هم میکنیم؛ دلیل خوبی براش داشته باشیم.
