سرعت، اولویت نیست!

گاها در تویتر یا از طریق ایمیل، پیغام‌هایی دریافت می‌کنم با این مضمون:

«… به نظرت کدوم زبان رو یاد بگیرم بهتره؟…»

اگر در ابتدای یادگیری برنامه نویسیم بودم، پاسخ من این می‌بود:

«فقط سی پلاس پلاس. هیچی رو دستش نیست. سرعتش از همه زبان ها بیشتره…..»

یکی دو سال بعدش جوابم این می‌بود:

«برو دنبال جاوا، اولین زبان برنامه نویسی دنیاست…»

و این جوابی بود که کمی بعدتر و با تجربه‌ی چند پروژه‌ی واقعی بهش رسیده بودم:

«هیچ کدوم این زبان ها پایتون نمیشن، هم راحت یاد میگیریش، هم راحت ازش استفاده میکنی…»

اما امروز که مدت ها از اون دوران میگذره، جواب من همیشه همینه:

«بهترین زبان، زبانی هست که باهاش احساس راحتی میکنی…»

و بعد از مدتی بحث (گاهی بحث طولانی میشه، چون من دوست دارم کسی که در برنامه‌نویسی تازه وارد هست رو راهنمایی و تشویق کنم؛ کاری که هیچ کس برای خودم انجام نداد…) دوست گرامی میرسه به جایی که میگه :

«من با فلان زبان راحت ترم، اما فکر کنم سرعتش خیلی بالا نیست…»

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

اول:

شما به عنوان تازه کاری که حتی هنوز خودش نمیدونه باید کدوم زبان رو انتخاب کنه، هیچ تصوری از مفهوم «سرعت» در سیستم های نرم افزاری ندارید! بنابراین نمیتونید بگید فلان زبان سریع هست یا نیست.

دوم:

«سرعت» یک موضوع کاملا نسبی هست. یعنی باید با توجه به عامل دیگه‌ای سنجیده بشه. میتونید بگید A به نسبت B سریع تر هست. یا کندتر هست. اما نمیتونید بگید سرعت A کم، یا زیاده. باید همیشه چیزی رو برای مقایسه داشته باشید.

سوم:

«سرعت» وابسته به «انتظارات» شماست! برای مثال، اگر انتظار شما از برنامه‌تان این است که یک جمله‌ی Hello World را در خروجی چاپ کنید، هیچ فرقی بین سرعت اسمبلی، سی، یا یک زبان سطح بالا مثل پایتون حس نخواهید کرد. در این شرایط تمام زبان‌های برنامه‌نویسی سریع هستند.

چهارم:

این سایت رو به عنوان منبع خودتون معرفی نکنید! وقتی برنامه‌نویسی این سایت رو به عنوان منبع معرفی میکنه، به سرعت نظرم راجع به سطح سوادش در زمینه‌ی برنامه‌نویسی عوض میشه! این سایت کاملا جنبه‌ی تفریح و فان داره و از نظر کاربردی قابل استناد نیست. حتی خودش هم همچین ادعایی نداره.

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

باید دقت کنید که:

  • هر الگوریتم‌، در هر زبانی به یک شکل پیاده‌سازی نمی‌شود. بسته به قابلیت‌های زبان، نحوه‌ی پیاده‌سازی الگوریتم متغیر هست.

  • هر الگوریتم، مناسب اجرا در هر زبانی نیست. بعضی از زبان‌ها در پیاده‌سازی بعضی از الگوریتم‌ها بهتر، و بعضی‌های دیگر بدتر عمل میکنن.

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

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

برای نمونه، در این بنچ‌مارک های به خصوص، زبان ‌های فانکشنال مشخصا به خاطر دارا بودن ساختارهای داده‌ای نامتغیر (immutable) هیچ وقت نمیدونن جلوی زبان‌های دستوری (imperative) خودی نشون بدن. آیا باید به این اعداد و ارقام استدلال کنیم و بگیم زبان‌های فانکشنال سرعت خوبی ندارن؟ آیا وقتی پای سیستم‌های واقعی وسط میاد بارها از مزایا و سرعت مناسب‌شون در سیستم‌های پروداکشن و واقعی نشنیدیم؟

پنجم:

یکی دیگه از سایت‌هایی که همیشه تو این بحث ها پاش میاد وسط این سایت (و سایت‌هایی شبیه اون) هست. این‌ها رو سرلوحه خودتون قرار ندید. اینکه فلان کمپانی با فلان زبان تونسته سیستمی طراحی کنه که در هر ثانیه میتونه پاسخ گوی فلان قدر کاربر باشه واقعا ربطی به شما نداره! بذارید این قضیه رو با یک مثال واقعی توضیح بدوم:

برای یکی از پروژه‌هام، من یک VPS خیلی کوچیک با ۵۱۲ مگابایت رم داشتم. یعنی خود سرور در حال اجرا روی یک سیستم مجازی ساز بود و پردازنده‌ی این سرور هم به صورت اشتراکی با بقیه VPS های موجود روی این سیستم استفاده میشد. روی این سرور، سرویسی در حال اجرا هست که در بدترین شرایط پاسخ گوی حداقل ۲۰۰ کاربر هم زمان هست. کار من این بود که برای این سرویس، یک کنترل پنل طراحی کنم. کنترل پنل من با مای‌اس‌کیو‌ال کار میکنه و با زبان پایتون نوشته شده. پایتون به خیلی چیزها معروفه، ولی سرعت اجرای برق‌آسا جزو اون‌ها نیست :) برای تفریح و تجربه، من تصمیم گرفتم یک بنچ‌مارک از این سیستم بگیرم. قبلش به این موارد دقت کنید:

– تمام موارد و نرم افزارهایی که بهشون اشاره کردم دارن روی همون سرور ۵۱۲ مگابایتی اجرای میشن. – هیچ بهینه‌سازی ای روی مای‌اس‌کیو‌ال، یا کدهای پایتون انجام ندادم. کاملا به صورت سَرسَری طراحی شدن. – خود پروسه‌ای که داره بنچ مارک رو انجام میده هم روی همین سیستم هست و روی سیستم فشار وارد میکنه.

بعد از بارها امتحان کردن، به این نتیجه رسیدم که کد من روی این سیستم میتونه در هر ثانیه پاسخ گوی ۱۱۰ درخواست ورودی باشه (به طور میانگین). هر روز معادل ۸۶۴۰۰ ثانیه اس. پس این سرور (جدای از کاربرهای سرویس اصلیش) میتونه روزانه پاسخ‌گوی ۹۵۰۴۰۰۰ (نه میلیون و پانصد و چهار هزار) درخواست ورودی باشه! حالا شما اصلا بگیر نه میلیون. سوال من اینه:

«چند تا وب سایت در ایران هستن که روزانه باید نه میلیون درخواست رو ساپورت کنن؟»

بذارید وسعت جغرافیایی رو بالاتر ببریم:

«چند تا وب سایت در جهان هستند که روزانه باید نه میلیون درخواست رو ساپورت کنن؟»

بنابراین اگر منطقی فکر کنید، متوجه میشید که برای قریب به اتفاق پروژه‌ها، اکثر زبان‌های برنامه‌نویسی میتونن سرعت مناسبی رو ارائه بدن و واقعا از نظر سرعت فرقی باهم ندارند! آیا اگر همین کد رو در Go یا Erlang یا ++C مینوشتم سرعت بهتری نمی‌گرفتم؟ چرا، احتمالش بود، اما آیا برای برنامه‌ای که نیاز داره در نهایت روزی ۵۰ تا پردازش رو انجام بده، فرق داره که بتونه نه میلیون درخواست رو ساپورت کنه یا نود میلیون؟

شاید بعد از خوندن مطالب بالا، به این نتیجه رسیدید که از این به بعد دیگه لازم نیست زیاد به سرعت فکر کنیم؛ اینطور که امیررضا میگه برنامه‌های ما به طور پیش فرض به اندازه کافی سریع هستن…همین جا توقف کنید…. مطالبی که من در بالا گفتم، فقط مثالی از اثبات یک مفهوم بود! یه برنامه نویس با تجربه میدونه که در سرور بالا و با توجه به توضیحاتی که راجع بهش دادم، اگر قرار باشه به صورت ممتد در هر ثانیه ۱۱۰ درخواست وارد سرور بشه، بعد از چند دقیقه افت سرعت ایجاد میشه و اگر این سیستم در نهایت بتونه روزانه ۲۰ هزار درخواست رو ساپورت کنه واقعا هنر کرده! اما من طوری جریان رو به شما توضیح دادم که شما فکر کنید سیستم من چقدر سریع هست! حالا متوجه منظورم شدید که صحبت درباره سرعت چقدر می‌تونه نسبی و وابسته به شرایط باشه؟ پشت هر بنچ‌مارک و اعداد و ارقامی که می‌بینید، داستان‌هایی وجود داره!

ششم:

موقع صحبت درباره سرعت، باید همیشه به مدل مصرف منابع سیستم هم توجه کنیم. مخصوصا حافظه، و ورودی و خروجی. فرضا یک اسکریپ نوشته شده در bash، میتونه ده ها برابر از کد معادلش در جاوا سریع‌تر باشه. اما آیا در عالم واقعیت جاوا کندتر از bash هست؟ آیا دلیل کند بودن جاوا نمیتونه این باشه که جاوا برای استفاده در همچین ابعاد کوچیکی طراحی نشده؟ اگر چنین طرز فکری داشته باشیم، پس همه‌ی زبان‌ها از bash کندتر هستند، بهتره که از فردا فقط با bash برنامه نویسی کنیم :)

زبان‌های مختلف در رابطه با منابع سیستم رویکردهای متفاوتی دارن. فرضا دو برنامه‌ی یکسان، یکی در پی‌اچ‌پی و یکی در جاوا طراحی کنید. این برنامه ها رو روی یک vps کوچک با ۲۵۶ مگابایت رم اجرا کنید. به احتمال خیلی زیاد متوجه میشید که پی‌اچ‌پی سرعت به مراتب بالاتری از جاوا رو در همچین شرایطی ارائه میده. حالا همین دو برنامه رو روی یک سرور با ۴ گیگ رم تست کنید، احتمالا نتیجه کاملا برعکس خواهد شد! زبانی مثل جاوا برای اجرای بهینه، نیاز به میزان نسبتا بالایی از منابع سیستم داره. بنابراین قبل از اینکه بخواید سرعت یک زبان رو محک بزنید، باید ببینید که آیا شرایط مناسب از نظر سخت افزاری را برای زبان محیا کرده اید یا خیر.

نتیجه:

سرعت مثل پول هست! هیچ کس به حدی که داره راضی نیست و هر چی که بیشتر بهش میرسید حریص تر میشید! مسلما یکی از نکات مهم در هر زبان برنامه‌نویسی و در هر سیستمی، عامل «سرعت» هست. اما سعی کنید در تصمیم گیری ‌هاتون سرعت رو به عنوان اولویت اول ارزیابی نکنید.

هرچه که تجربه‌تون در برنامه‌نویسی بیشتر میشه، بیشتر به این قضیه میرسید که برای ۹۹٪ برنامه‌نویس ها، و ۹۹٪ پروژه‌ها، سرعت واقعا عامل تعیین کننده‌ای نیست.

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

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

نظرات

comments powered by Disqus