کندی نرمافزار از طراحی بده، نه از زبان برنامهنویسی
خلاصهٔ کاملتر
این روزها خیلیها میگن AI قراره نرمافزارها رو با بازنویسی به زبونهای سریعتر، سریعتر کنه. Sean Goedecke تو این مقاله میگه این حرف معمولاً درست نیست. درسته که C میتونه تا ۵۰ برابر از Python سریعتر باشه، ولی این به این معنی نیست که برنامهی شما هم ۵۰ برابر سریعتر میشه. به گفتهی نویسنده، سرعت نرمافزار بیشتر یه مسئلهی طراحی هست تا انتخاب زبان.
دلیل اول اینه که بیشتر برنامههای واقعی I/O-bound هستن، یعنی بیشتر وقتشون منتظر خوندن و نوشتن داده میمونن، نه محاسبه. مثلاً تو یه سایت CRUD ممکنه ۵۰ درصد زمان هر درخواست صرف کوئریهای دیتابیس بشه. اگه کل سایت رو به C بازنویسی کنی، فقط اون ۵۰ درصد دیگه سریعتر میشه. این همون Amdahl's law هست، یعنی سقف سرعتگرفتن رو بخشی تعیین میکنه که بهبود نمیدی. پس در بهترین حالت دو برابر سریعتر میشی و تو عمل حدود ۱.۵ برابر. ابزاری مثل curl هم اگه ۱۰۰ برابر سریعتر بشه، احتمالاً فرقی حس نمیکنی، چون کل وقتش منتظر شبکهست.
دلیل دوم اینه که زبونهای کند از قبل کارهای سنگین رو به زبونهای سریع میسپرن. مثلاً تبدیل markdown به HTML با کتابخونههایی مثل cmark-gfm انجام میشه. Python هم با PyTorch و TensorFlow ضرب ماتریسها رو به کد C یا اسمبلیِ بهینهشده یا GPU میده. پس برنامهای که ۸۰ درصد وقتش ضرب ماتریسه، با بازنویسی به C تقریباً سریعتر نمیشه. نویسنده قبول داره که برنامههای CPU-bound بهینهنشده هم هستن، ولی میگه اینا معمولاً مهم نیستن، وگرنه یکی قبلاً بهینهشون کرده بود.
یه مثال جالب از Bryan Cantrill هست که سال ۲۰۱۸ میخواست یه برنامهی C رو به Rust ببره. چون طراحیِ دقیق نسخهی C با borrow checker در Rust جور درنمیومد، برنامه رو به سادهترین شکل نوشت و انتظار داشت ۲۰ درصد کندتر بشه. ولی نتیجه ۳۰ درصد سریعتر بود، چون Rust بهجای binary search tree از B-tree استفاده میکنه که با کش CPU بهتر کار میکنه. یعنی حتی اینجا هم طراحی برنده شد. حتی بازنویسی tiktoken به اسمبلی هم که حدود ۵ برابر سریعتر شد، به گفتهی نویسنده بیشتر به خاطر حذف وابستگی به regex بود.
نویسنده از تجربهی خودش میگه تقریباً همهی بهبودهای جدیای که گرفته، از کمکردن کار برنامه اومده: کشکردن عملیات کند مثل API call، بردن کارها به background job، موازیکردن کارها، حل مشکل N+1 (یعنی وقتی بهجای یه کوئری، دهها کوئری جدا میزنی)، سریعکردن کوئریهای SQL و رد کردن کارهای غیرضروری. هیچکدوم از اینا به سرعت زبان ربطی ندارن. حتی زبون سطح بالا کمک میکنه، چون راحتتر میبینی برنامه داره چی کار میکنه.
توصیهی نویسنده اینه که بهجای اینکه از agent بخوای کل برنامه رو به Rust بازنویسی کنه، ازش بخوای برنامه رو profile کنه، نقطههای داغ رو پیدا کنه و راههای بازطراحی پیشنهاد بده. فقط اگه یه بخش واقعاً CPU-bound بود و نمیشد کارش رو کم کرد، همون بخش رو با زبون سریعتر بنویس.
نکات کلیدی:
- بیشتر برنامههای واقعی I/O-bound هستن و سرعت زبان روی اونا اثر کمی داره.
- طبق Amdahl's law، اگه ۵۰ درصد زمان درخواست صرف دیتابیس بشه، بازنویسی به C حداکثر دو برابر سرعت میده.
- Python برای ML سریعه چون PyTorch و TensorFlow کار سنگین رو به C و GPU میدن.
- بازنویسی سادهی یه برنامهی C به Rust به خاطر B-tree حدود ۳۰ درصد سریعتر شد.
- کش، background job، موازیسازی و حل N+1 بیشترین اثر رو روی سرعت دارن.
- بهتره از AI بخوای profile کنه و hotspot پیدا کنه، نه اینکه کل کد رو بازنویسی کنه.




