خانه توسعهدهنده تکنولوژی بکاند جنگو آیا جنگو یک فریم ورک سریع است؟
آیا جنگو یک فریم ورک سریع است؟
هیچ شکی وجود ندارد که تقاضا برای استخدام برنامه نویس جنگو در دنیا بسیار بالاست؛ به طوری که امروزه بیش از 100 هزار موقعیت شغلی مربوط به جنگو در آمریکا وجود دارد. به این ترتیب، این فریمورک یکی از محبوبترین فریمورکهای تحتوب پایتون به حساب میآید. این موضوع باعث میشود تا روز به روز افراد بیشتری به سمت آموزش جنگو متمایل شوند. اما عملکرد این فریمورک به چه صورت است؟ آیا جنگو یک فریم ورک سریع است؟
در این مقاله، به بررسی سرعت این فریمورک محبوب و پرکاربرد میپردازیم و به این سؤال پاسخ میدهیم که آیا جنگو یک فریم ورک سریع است یا نه؟ و در ادامه نکاتی را برای بهبود عملکرد اپلیکیشنهای نوشته شده با جنگو ارائه میدهیم. پس تا انتهای این مطلب، همراه کوئرا بلاگ باشید.
فهرست مطالب
Toggleفریمورک های پایتون
همانطور که گفتیم، جنگو یکی از فریمورکهای پایتون است. اما به طور کلی فریمورک یعنی چه؟ و چه نمونههای دیگری از فریمورک پایتون وجود دارند؟
فریم ورک چیست؟
فریمورک در لغت به معنای چارچوب یا زیربنای یک سیستم است. عملکرد آن هم خیلی دور از این تعریف نیست. چرا که یک فریمورک به نوعی راهنما و حامی ساختار سیستم مورد نظر است و کامپوننتها و راهحلهایی سفارشی برای افزایش سرعت توسعه ارائه میکند.
یک فریمورک، توسط اصل معکوس کردن کنترل (IoC) تعریف میشود. با استفاده از IoC، فریمورک در صورت نیاز، به قطعات کد سفارشی مراجعه میکند. این در حالی است که در برنامهنویسی سنتی، کد سفارشی برای دستیابی به کد قابل استفاده مجدد، به کتابخانه مراجعه میکند.
چند نمونه از فریمورکهای پایتون
فریمورک پایتون، فریمورکی است که زیرساخت پایه برای توسعه یک برنامه نرمافزاری پایتون قدرتمند فراهم میکند. چند نمونه از بهترین فریمورکهای پایتون عبارتاند از:
- Django
- flask
- Web2py
- AIOHTTP
- CherryPy
- Dash
- Falcon
حالا که با فریمورکهای پایتون آشنا شدید خوب است به پاسخ این سوال بپردازیم که آیا جنگو یک فریم ورک سریع است؟ و آیا در مقایسه با دیگر فریمورکها عملکرد خوبی دارد؟
مقایسه جنگو با سایر فریمورکها
به این بنچمارک دقت کنید. در این تست، یک سرور برای هر فریمورک ساخته شده است. سپس یک فایل json ساده به هر سرور ارسال و در نهایت تعداد ریکوئستهایی که در ثانیه توسط سرور پردازش شدهاند، نوشته شده است.
همانطور که میبینید جنگو در همهی تستها جزء کندترین فریمورکها است، اما این مدل اندازهگیری چندان مناسب نیست؛ چون اولاً این پروژه به پروژههای دنیای واقعی آنقدر نزدیک نیست و کمتر پیش میآید که ما بخواهیم یک فایل ثابت را برای همهی کاربران بفرستیم یا بهعنوان مثال در ExpressJS فقط 3 لایهی ساده از middlewareها وجود دارد، ولی در جنگو مجموعهی بزرگی از middlewareها وجود دارد که کارهای مختلفی روی ریکوئست انجام میدهند. (middlewareها عملکردهای خاصی را در طول مسیر روی request انجام میدهند.)
ممکن است علاقهمند باشید: جنگو (django) چیست؟
Performance چیست؟
وقتی یک نفر به شما میگوید که یک فریمورک خیلی کند است، باید از او بپرسید که در چه زمینهای کند است و چرا این کندبودن اهمیت دارد؟
بهطورکلی برای بهینهتر کردن سایت دو هدف وجود دارد : اول اینکه کاربر تجربهی بهتری از کار با سایت داشته باشد و دوم اینکه هزینههای سرور و نگهداری سایت پایین بیاید. بیایید به اولی بپردازیم. وقتی کاربر با سایت کار میکند دو مورد اهمیت پیدا میکنند:
- Response time یعنی زمانی که کاربر باید صبر کند تا صفحه برایش لود شود.
- Concurrency یعنی چند کاربر میتوانند بهطور همزمان از سایت استفاده کنند.
در ادامه دربارهی این دو پارامتر بیشتر صحبت میکنیم.
Response time در جنگو
کاربران دوست ندارند که برای لودشدن صفحه منتظر بمانند؛ پس هرچه صفحه سریعتر لود شود، کاربران از عملکرد سایت شما رضایت بیشتری دارند. اما رابطهی بین زمان لودشدن صفحه و میزان رضایت کاربر، یک رابطهی خطی نیست؛ برای مثال اگر صفحهی وبسایت شما قبلاً در 5 ثانیه لود میشده و الان کاری کردهاید که در 1 ثانیه لود میشود، این بهبود در سایت شما کاربر را خوشحال میکند.
حتی اگر صفحهای قبلاً در 500 میلیثانیه لود میشده و الان در 100 میلیثانیه لود میشود، باز هم این بهبود باعث رضایت بیشتر کاربران میشود. ولی اگر سرعت لودشدن را از 50 میلیثانیه به 10 میلیثانیه برسانید، احتمالاً کسی متوجه این تغییر نمیشود. پس وقتی میگویند این فریمورک از آن فریمورک 5 برابر سریعتر است، لزوماً به این معنی نیست که قرار است تجربهی کاربری خیلی بهتری را برای کاربران فراهم کند.
Concurrency در جنگو
بالاتر نیز به این مسئله اشاره کردیم که Concurrency یعنی چند کاربر میتوانند بهطور همزمان از سایت استفاده کنند. یکی از مسئلههای اصلی در Concurrency ارتباط برقرارکردن با دیتابیس و دریافت دیتا از آن است. در اینجا چیزی که خیلی میتواند تأثیرگذار باشد مهارت برنامهنویس، استفادهی بهینه از دیتا و کمکردن تعداد ریکوئستها به دیتابیس است.
مسئول رسیدگی به Concurrency در جنگو، سرور wsgi (Web Server Gateway Interface) است. wsgiهای مختلفی در پایتون وجود دارد که از جملهی آنها میتوان به Bjoern ،Gunicorn، Meinheld و … اشاره کرد که هرکدام مزیتهای خاصی داشته و از پرفورمنس بالایی نیز برخوردارند.
پس در نهایت میتوان گفت که concurrency در جنگو بیشتر به شما و قدرت سروری که میتوانید تهیه کنید بستگی دارد و هرچه رم و هستههای پردازنده سرور خود را ارتقا دهید جنگو هم با شما همراهی کرده و امکان افزایش concurrency را میدهد.
برای اینکه بفهمید با سروری که تهیه کردید چه مقدار concurrency خواهید داشت، میتوانید از ابزار Locust استفاده کنید که کاربران را شبیهسازی کرده و با ارسال تعداد زیادی ریکوئست سایت شما را به چالش میکشد.
Performance از زاویه دیگر
از زاویهی دیگری هم میتوان به Performance نگاه کرد و آن بهرهوری خود شما بهعنوان یک دولوپر است. اینکه شما بتوانید پروژهی خود را زودتر تمام کرده یا باگها را سریعتر فیکس کنید و وقت بیشتری برای اضافه کردن featureهای جدید داشته باشید هم نوعی بهرهوری محسوب میشود که در این مورد جنگو حرفهای زیادی برای گفتن دارد. از داکیومنتهای گسترده گرفته تا سؤالات متعددی که در Stack Overflow و سایر سایتها جواب داده شدهاند و همچنین زبان پایتون که نسبت به بقیهی زبانها سادهتر و قابلفهمتر است؛ همه اینها باعث میشوند که شما بتوانید یک پروژهی جنگو را خیلی سریع و با بهرهوری بالا توسعه دهید.
نکاتی برای سریعتر شدن اپلیکیشنهای ساخته شده با جنگو
«سادگی و تجربه کاربری رضایتبخش همیشه پیروز میشود». احتمالا همه ما با این ادعا موافق هستیم. سرعت نیز یکی از ویژگیهای تاثیرگذار بر تجربه کاربری است. پس در این بخش میخواهیم نکاتی را برای افزایش سرعت و راندمان برنامههای جنگویی بیان کنیم.
کاهش میزان کوئریها و بهینهسازی
روند معمول به سرانجام رسیدن یک درخواست (request) به این صورت است که شما درخواستی از بخش Front برای بازیابی اطلاعات از دیتابیس دریافت کرده و پس از اصلاح، آن را به عنوان یک JSON response object ارسال میکنید.
کوئریها برای به دست آوردن اطلاعات مورد نظر، تک تک بخشهای SQL که میتواند دارای صدها رکورد باشد را جستجو میکنند. بنابراین بازیابی اطلاعات از دیتابیس از بقیه بخشهای انجام یک درخواست، زمان بیشتری میبرد. حال مشکل از جایی درست میشود که معمولا به سبب وجود ویژگی ORM در جنگو، بدون ملاحظه از کوئریهای زیادی استفاده میشود. اگر این کوئریها بهینهسازی نشوند میتوانند بازده جنگو را با مشکلات جدی مواجه کنند.
برخی از راههای بهینهسازی:
- هنگام استفاده از مدل رابطهای، از کلید select_related و prefetch_related استفاده کنید.
- تا حد امکان استفاده از فیلترها را جایگزین حلقه for کنید.
- کوئریهای خود را در متغیرها ذخیره کنید تا بتوانید در آینده از آنها استفاده کنید و نیازی به اجرای مجدد نباشد.
ناهمگامسازی کارها با استفاده از celery
زمانی که ازبرنامههایی در مقیاس بالا استفاده میکنید، ناهمگام سازی کارها میتواند بار زیادی از روی دوش cpu برداشته و به سرعت پروژه شما کمک زیادی بکند. این به این معناست که هربخش به صورت مستقل انجام شده و برنامه، اجرای دیگر بخشها را پردازش میکند و در انتظار نتیجه آنها نیست.
برای این کار میتوانید از کتابخانهی celery استفاده کنید. celery یک صف کار(Task queue) است که بر روی اجرای درلحظهی کارها و قابلیت زمانبندی آنها تمرکز دارد. با استفاده از Celery، میتوانید وظایف (tasks) را ایجاد کنید. چندین ورکر به صورت جداگانه روی تسکها کار میکنند که این عدد به صورت پیشفرض در Celery روی ۴ است. هر بار که یک وظیفه به صف کار اضافه میشود، اولین ورکری که آزاد است، آن را دریافت کرده و اجرا میکند. اگر چندین وظیفه به صورت همزمان به صف اضافه شوند، هر ورکر یکی از آنها را دریافت میکند تا تمام آنها مشغول شوند.
هرگاه یکی از آنها تسک را به پایان برساند، تسک بعدی در صف را دریافت و اجرا میکند تا همگی آنها به انجام برسند. ورکرها به صورت همزمان ممکن است روی چند تسک کار کنند؛ به همین دلیل است که از کلمه ناهمگامسازی استفاده میکنیم. همچنین، به این دلیل که این فرآیند ناهمگام است، هیچ کنترلی بر روی ترتیب اتمام اجرای وظایف وجود ندارد. اولین وظیفه اضافه شده به صف، ممکن است آخرین وظیفهای باشد که به پایان میرسد. این مسئله باعث میشود تا برنامه شما تحت تاثیر زمان اجرای هر تسک نباشد و حتی اگر تسکی به مشکل خورد روی برنامه تاثیری نداشته باشد.
خودداری از نوشتن عملکردها یا اشیائی که از قبل وجود دارند
یکی از اولین قواعد برنامهنویسی، اصل DRY یا Don’t Repeat Yourself است. طبق این اصل شما نباید خودتان را تکرار کنید. این کار میتواند برای عملکرد برنامه شما بسیار آسیبزا باشد چرا که معمولاً کدی که تکرار میشود، کندتر از کدی است که با هسته کتابخانه ارائه میشود. اگرچه این مورد ممکن است کمی بدیهی به نظر برسد. اما اشتباهی بسیار تاثیر گذار در پایین آمدن عملکرد جنگو است.
کشینگ اطلاعات قابل پیشبینی
زمانی که اطلاعاتی دارید که احتمال تغییر بسیار کمی دارند بهتر است آنها را کش کنید. کشینگ به معنای حفظ بخشی از اطلاعات در یک حافظه نهان به منظور بهبود عملکرد سیستم و دسترسی سریعتر به اطلاعات است. Django یک حافظه نهان سطح پایین فراهم میکند که به شما امکان ذخیره یک سری داده خاص را میدهد، بدون آنکه مجبور شوید کل صفحه را در حافظه نهان ذخیره کنید. به مثال زیر توجه کنید:
from django.core.cache import cache
cache.set('my_key', 'hello, world!', 30)
cache.get('my_key')
cache.clear()
این متد در شرایطی که نیازی به اطلاعات به روز نیست میتواند بسیار مفید بوده و عملکرد برنامه را به شدت بهبود بخشد.
Clean Code و دیگر هیچ!
Clean Code یا زدن کد تمیز نه تنها روند توسعه برنامه را آسانتر میکند، بلکه در عملکرد آن نیز بسیار تاثیر گذار است. نکات مهمی که میتوانید در این زمینه رعایت کنید:
- هیچ کدی نباید در برنامه شما تکرار شود. اگر بخشی از کد تکرار میشود، برای آن یک تابع یا متد بسازید.
- عموما یک تابع یا متد، باید به ازای هر پردازش یک بار تکرار شود. اگر نیاز دارید از نتایج آن استفاده کنید، آن را درون یک متغیر لوکال ذخیره کرده و از این متغیر استفاده کنید.
- از پردازشهای غیرضروری در متد __init__ اشیاء خود، خودداری کنید. اگر چیز سنگینی مانند یک درخواست خارجی وجود دارد، آن را در متد دیگری نگه دارید تا بتوانید این که چه زمانی آن را صدا بزنید را مدیریت کنید.
- به دنبال متغیرها و متدهای استفاده نشده بگردید. ممکن است برنامه شما زمان زیادی را صرف اجرای متدی کند که نتایج آن در هیچجا استفاده نمیشود. برای انجام این کار، ویرایشگرهای کد زیادی میتوانند به شما کمک کنند.
نتیجهگیری
بهطورکلی جنگو بهرهوری مناسبی برای اکثر پروژهها دارد و پروژههای زیادی با این فریمورک نوشتهشدهاند. سادگیِ نوشتن و دیباگکردن هم مسئلهای است که واقعاً به محبوبیت این فریمورک اضافه کرده است. اما آیا جنگو یک فریم ورک سریع است؟ پاسخ کلی این است که جنگو سریعترین گزینه موجود برای انجام کارهایتان نیست!
اگر شما پروژهای دارید که لازم است خیلی سریع باشد و میلیثانیهها هم برایتان اهمیت دارند یا اینکه سرور و سختافزارهای لازم برای اجرای پروژهی جنگو را ندارید، میتوانید از فریمورکهای دیگری که سرعت بالاتری دارند استفاده کنید.
امیدواریم از خواندن مقاله «آیا جنگو یک فریم ورک سریع است؟» لذت برده باشید. خوشحال میشویم تا نظرات یا ابهامات خود را از طریق کامنت با ما در میان بگذارید.