روشهایی برای بالا بردن سرعت برنامه های پایتون

11 روش برای افزایش سرعت پایتونبه طور کلی ، افراد از Python به دلیل راحت بودن و سهولت برنامه نویسی استفاده می کنند ، نه به دلیل سریع بودن آن. انبوه کتابخانه های شخص ثالث و گستردگی پشتیبانی از پایتون ضعف سرعت آن در مقابل جاوا یا C را جبران می کند. .در واقع باید گفت سرعت توسعه بر سرعت اجرا اولویت دارد.اما در بسیاری از موارد ، لازم نیست که سرعت را فدا کنید .با بهینه سازی مناسب ، برنامه های پایتون می توانند با سرعت شگفت انگیزی اجرا شوند . نه به سرعت جاوا یا C ، اما به اندازه کافی سریع برای برنامه های وب ، تجزیه و تحلیل داده ها ، ابزارهای مدیریت و اتوماسیون و سایر اهداف. در واقع ممکن است فراموش کنید که برای بالا بردن سرعت توسعه ، عملکرد برنامه را فدا کرده اید.مقدمهبهینه سازی عملکرد پایتون به یک عامل بر نمی گردد. در عوض ، این مهم با بررسی تمامی راه های خوب و انتخاب روشهایی به دست می آید که متناسب با سناریوی موجود باشد. (کدنویسان در Dropbox یکی از بهترین نمونه های قدرت بهینه سازی در پایتون را نشان می دهند).در این بخش بهینه سازی های رایج پایتون را برای افزایش سرعت پایتون به طور خلاصه بیان می کنم. برخی از آنها اقدامات هستند که به بیش از تغییر یک مورد برای مورد دیگر نیاز دارند. (مانند تغییر interpreter پایتون) . اما مواردی که بیشترین بازده را دارند بالطبع به ظریف کاری بیشتری نیز نیاز دارند.اندازه گیری ، اندازه گیری ، اندازه گیریشما نمی توانید بفهمید که چرا برنامه Pythonتان در عملکرد ضعیف است بدون اینکه بدانید این ضعف در سرعت از کجای کد برنامه تان ناشی می شود.از طریق ماژول cProfile داخلی پایتون شروع به پروفایل کردن برنامه تان کنید . اگر به دقت بیشتری یا عمق بینش بیشتری نیاز دارید ، به یک پروفایلر قدرتمندتر بروید . اغلب اوقات ، داده های حاصل از بررسی سطح عملکرد یک برنامه ،با همان پروفایلر ساده بیش از حد کافی است.اینکه چرا یک قسمت خاص از برنامه بسیار کند است و نحوه رفع آن ممکن است جست و جو و تحقیق بیشتری بطبد. هدف این است که دایره تمرکز را کوچک کنید . یک خط مبنا ایجاد کنید و هر زمان که ممکن است سناریوهای مختلف استفاده و آزمایش را تست کنید.کورکورانه شروع به بهینه سازی نکنید. حدس و گمان شما را به جایی نمی رساند.مثالی که در بالا از Dropbox پیوند داده شده است ، نشان می دهد که چقدر profiling مفید است. کدنویسان در این مقاله نوشته اند: “این اندازه گیری بود که به ما گفت HTML escaping برای شروع کند است.”و بدون اندازه گیری عملکرد ، هرگز گمان نمی بردیم که interpolation رشته بسیار کند است. “داده های مورد استفاده پرتکرار را به خاطر بسپارید (cache)هرگز یک کار را هزار بار تکرار نکنید وقتی می توانید یک بار آن را انجام دهید و نتیجه را ذخیره کنید. اگر تابعی دارید که مرتباً فراخوانی می شود و نتایج قابل پیش بینی را برمی گرداند ، پایتون گزینه هایی را برای ذخیره سازی نتایج در حافظه به شما ارائه می دهد. فراخوانی های بعدی که همان نتیجه را برمی گردانند ، تقریباً آنی اجرا می شوند.مثالهای مختلفی برای انجام این کاروجود دارد.نمونه مورد علاقه من را از اینجا ببینید . اما پایتون این قابلیت را در درون خود دارد. یکی از کتابخانه های بومی پایتون ، functools ، دارای دکوراتور @functools.lru_cache است که nتا از آخرین تماس های یک تابع را در آن ذخیره می کند. این زمانی مفید است که مقداری که ذخیره می کنید تغییر می کند اما در یک بازه زمانی خاص نسبتاً ثابت است. لیستی از مواردی که اخیرا در طول روز استفاده شده مثال خوبی است.توجه داشته باشید که اگر مطمئن هستید تنوع تماس با functionدر حد معقولی باقی می ماند. (به عنوان مثال 100 نتیجه مختلف در cached) . می توانیداز @functools.cache به جای آن استفاده کنید که عملکرد بهتری دارد. راههای زیبادی برای افزایش سرعت پایتون موجود است . این یکی از آن هاست.ریاضیات را به NumPy منتقل کنیداگر شما ریاضیات مبتنی بر ماتریس یا آرایه انجام می دهید و نمی خواهید مفسر پایتون جلوی دست و پایتان را بگیرد ، از NumPy استفاده کنید . NumPy با استفاده از کتابخانه های C برای انجام محاسبات سنگین ، پردازش آرایه را سریعتر از پایتون بومی انجام می دهد. همچنین داده های عددی را با کارایی بیشتری نسبت به ساختار داده های داخلی پایتون ذخیره می کند.ریاضیات و محاسبات نه چندان پیچیده را نیز می توان توسط NumPy با سرعت فوق العاده بیشتری پیاده سازی کرد. این بسته جایگزینی برای بسیاری از عملگرهای رایج ریاضی پایتون مانند ، minو max، ارایه می دهد که چندین برابر سریعتر از نسخه اصلی پایتون عمل می کنند.مزیت دیگر NumPy استفاده کارآمدتر از حافظه برای object های بزرگ ، مانند لیست هایی با میلیون ها داده است. به طور میانگین​​، object های بزرگی مانند این در NumPy حدود یک چهارم حافظه مورد نیاز(مورد نیاز برای محیط بومی خود پایتون) را اشغال می کنند . توجه داشته باشید که کار بر روی ساختار داده درست از همان ابتدا خود عاملی بر بهبود عملکرد برنامه استوبازنویسی الگوریتم های پایتون برای استفاده از NumPy کمی طول می کشد. زیرا آرایه object ها باید با استفاده از سینتکس NumPy استفاده شوند. اما NumPy از اصطلاحات موجود پایتون برای عملیات ریاضی (+ ، – ، و غیره) استفاده می کند . بنابراین تغییر به NumPy در طولانی مدت خیلی گمراه کننده نیست.ریاضیات را به Numba منتقل کنیدیکی دیگر از کتابخانه های قدرتمند برای سرعت بخشیدن به کارهای ریاضی ، Numba است . مقداری کد پایتون برای دستکاری عددی بنویسید و آن را با کامپایلر Numba’s JIT امتحان کنید . کد بدست آمده با سرعت بومی ماشین اجرا می شود. Numba نه تنها شتاب دهنده های مربوط به پردازنده گرافیکی (هم CUDA وهم ROC) را فراهم می کند . بلکه دارای یک حالت “nopython” ویژه است که سعی می کند با اعتماد نکردن به مفسر Python تا جایی که ممکن است عملکرد را به حداکثر برساند.بدانید که Numba با NumPy نیز به خوبی عمل می کند. بنابراین می توانید بهترین ها را از هر دو بدست آورید . NumPy برای تمام عملیاتی که می تواند حل کند و Numba برای باقی مسایل.از کتابخانه C استفاده کنیداستفاده NumPy از کتابخانه های نوشته شده در C استراتژی خوبی برای پیاده سازی است. اگر یک کتابخانه C وجود دارد که آنچه شما نیاز دارید را انجام می دهد . پایتون و اکوسیستم آن چندین گزینه برای اتصال به کتابخانه و استفاده از سرعت آن را ارائه می دهد.متداول ترین روش برای انجام این کار کتابخانه ctypes پایتون است . از آنجا که ctypes به طور گسترده ای با سایر برنامه های Python (و runtimes) سازگار است ، بهترین مکان برای شروع است .اما گمان نکنید تنها انتخابتان همین است. CFFI یک رابط ظریف تر و زیباتر به C را ارایه می دهد.از Cython(پایین را ببینید) نیز می توان برای در هم پیچیدن کتابخانه های خارجی استفاده کرد هر چند هزینه اش یادگیری آن است.یک نکته مهم در اینجا: با به حداقل رساندن تعداد رفت و برگشت ها از C به پایتون ، بهترین نتیجه را خواهید گرفت. هر باری که داده ای را بین آنها انتقال می دهید ، یک ضربه به عملکرد می زنید. اگر بین یک کتابخانه C در یک حلقه فشرده و در مقابل انتقال کل ساختار داده به کتابخانه C و انجام پردازش درون حلقه ای در آنجا حق انتخاب دارید ، گزینه دوم را انتخاب کنید.تبدیل به Cythonاگر سرعت می خواهید ، از C استفاده کنید نه از پایتون. اما برای عاشقان پایتون، نوشتن کد C دردسر های خود را دارد . یادگیری سینتکس C ، بهم ریختگیc toolchain (حالا هدر فایل هام چه مرگش شد؟) و غیره.سایتون به کاربران پایتون اجازه می دهد تا به راحتی به سرعت C دسترسی پیدا کنند.کد موجود پایتون را می توان به تدریج به C تبدیل کرد – ابتدا با compile کد گفته شده به C با Cython ، سپس با افزودنtype annotations برای سرعت بیشتر.سایتون یک عصای جادویی نیست. کدی که به Cython تبدیل شده است معمولاً بیش از 15 تا 50 درصد سریعتر اجرا نمی شود. زیرا بیشتر بهینه سازی ها در آن بر کاهش سطح سربار روی مفسر پایتون متمرکز است. بیشترین عملکرد زمانی است که برای انواع ماژول سایتون type annotations تهیه می کنید و اجازه می دهید کد مورد نظر به C خالص تبدیل شود. سرعت کد حاصله فراتر از حد تصورتان سریع تر می شود.کد متصل به CPU بیشترین بهره را از Cython می برد. اگر پروفایل خود را تنظیم کرده اید. (پروفایل را تنظیم کردید دیگه؟) و متوجه شده اید که قسمت های خاصی از کد شما از اکثریت قریب به اتفاق زمان پردازنده استفاده می کند . این قسمت ها از کد گزینه های بسیار خوبی برای تبدیل به Cython هستند. کدی که به I / O محدود باشد ، مانند عملیات طولانی مدت شبکه ، فایده کمی از Cython خواهد بود اگر اصلا فایده ای ببرد.همانند استفاده از کتابخانه های C ، نکته مهم دیگر در زمینه افزایش عملکرد این است که تعداد رفت و برگشت های به Cython را نیز به حداقل برسانید. حلقه ای ننویسید که عملکرد “Cythonized” را به طور مکرر فراخوانی کند. حلقه را در Cython پیاده سازی کرده و داده ها را به یک باره منتقل کنید.با پردازش چندگانه موازی جلو برویدبرنامه های سنتی پایتون – آنهایی که در CPython پیاده سازی شده اند . برای جلوگیری از مشکلات که هنگام استفاده از چندین THREAD پیش می آید ، هر بار فقط یک thread را اجرا می کنند. این همان Global Interpreter Lock (GIL) معروف است. اینکه دلایل خوبی برای وجود آن وجود دارد باعث نمی شود که به همان اندازه نامطلوب نباشد.مساله GIL با گذشت زمان بسیار کارآمدتر شده است اما مسئله اصلی همچنان وجود دارد . یک برنامه CPython می تواند چند رشته ای باشد . اما CPython در واقع اجازه نمی دهد که آن رشته ها به طور موازی روی چندین هسته اجرا شوند.برای دور زدن آن ، پایتون ماژول چند پردازشی را برای اجرای چندین نمونه از مفسر پایتون در هسته های جداگانه فراهم می کند . State را می توان از طریق حافظه مشترک یا فرایندهای سرور به اشتراک گذاشت و داده ها را می توان از طریق queues یاpipes بین نمونه های پردازش منتقل کرد.شما هنوز هم باید بین state ها به صورت دستی وضعیت را مدیریت کنید. اما برای فرآیندهای طولانی مدت که از موازی کاری در هسته ها بهره مند می شوند ، کتابخانه چند پردازشی مفید است.بعلاوه ، ماژول ها و بسته های پایتون که از کتابخانه های C استفاده می کنند (مانند NumPy یا Cython) می توانند به طور کامل از GIL جلوگیری کنند. این دلیل دیگری است که آنها برای افزایش سرعت توصیه می شوند.بدانید کتابخانه های شما چه می کنندچقدر راحت است که فقط تایپ کنید include harchiو از کارهای برنامه نویسان دیگر استفاده کنید! اما باید توجه داشته باشید که کتابخانه های شخص ثالث می توانند عملکرد برنامه شما را تغییر دهند. اما این همیشه به سمت مثبت نیست.گاهی اوقات این ضربه ها به روشهای واضحی آشکار می شود ، مانند زمانی که یک ماژول از یک کتابخانه خاص یک bottleneck تشکیل می دهد. (باز هم ، پروفایل کمک خواهد کرد.) اما گاهی اوقات کمتر مشخص است. مثال: Pyglet . یک کتابخانه مفید برای ایجاد برنامه های گرافیکی . که به طور خودکار حالت اشکال زدایی را فعال می کند ، و تا زمانی که به طور قطع به یقین غیرفعال نشود ، عملکرد را به طور چشمگیری تحت تأثیر قرار می دهد. ممکن است هرگز متوجه این موضوع نشوید. مگر اینکه مستندات را بخوانید.پس بخوانید و مطلع شوید.حواستان به سیستم عامل باشدپایتون از کراس پلتفورم پشتیبانی می کند . اما این بدان معنا نیست که ویژگی های هر سیستم عامل – ویندوز ، لینوکس ، سیستم عامل X – تحت نظر پایتون مدیریت می شوند. بیشتر اوقات ، این بدان معنی است که از مشخصات پلت فرم مانند نامگذاری مسیری که توابع کمکی برای آن وجود دارند آگاهی داشته باشید.ماژول pathlib ، برای مثال، برای این مورد کمک می کند.اما درک تفاوت سیستم عامل نیز در مورد عملکرد مهم است. به عنوان مثال ، در ویندوز . اسکریپت های پایتون که به دقت تایمر بهتر از 15 میلی ثانیه نیاز دارند (مثلاً برای چندرسانه ای)باید از تماس های API ویندوز برای دسترسی به تایمرهای با وضوح بالا یا بالا بردن وضوح تایمر استفاده کرد.از PyPy استفاده کنیدCPython که معمولاً بیشترین استفاده در پایتون را دارد . سازگاری را نسبت به سرعت در اولویت قرار می دهد. برای برنامه نویسانی که می خواهند سرعت را در درجه اول قرار دهند ، PyPy وجود دارد . یک اجرا از Python مجهز به یک کامپایلر JIT برای سرعت بخشیدن به اجرای کد.از آنجا که PyPy به عنوان جایگزینی برای CPython طراحی شده است ، یکی از ساده ترین راه ها برای افزایش سریع عملکرد است. بسیاری از برنامه های رایج پایتون دقیقاً همانطور که هستند روی PyPy اجرا می شوند. به طور کلی ، هرچه برنامه بیشتر به پایتون “vanilla” متکی باشد ، احتمال اجرای آن بدون تغییر در PyPy بیشتر است.با این حال ،برای استفاده مفید تر از PyPy نیاز به آزمایش و مطالعه است. خواهید دید که برنامه های طولانی مدت بیشترین بهبود عملکرد را از PyPy به دست می آورند. زیرا کامپایلر به مرور زمان اجرا را تجزیه و تحلیل می کند. برای اسکریپت های کوتاه که اجرا و خارج می شوند ، بهتر است از CPython استفاده کنید ، زیرا افزایش عملکرد برای غلبه بر سرباری که JIT ایجاد می کند کافی نخواهد بود.توجه داشته باشید که پشتیبانی PyPy از پایتون 3 هنوز چندین نسخه عقب است. در حال حاضر از پایتون 3.2.5 پشتیبانی می کند. کدی که از ویژگی های نسخه های جدید پایتون استفاده می کند ، مانند async و await ،پشتیبانی نمی شود. در نهایت، برنامه های پایتون که از ctypes استفاده می کنند ممکن است همیشه مطابق انتظار رفتار نکنند . اگر در حال نوشتن برنامه ای هستید که ممکن است هم روی PyPy و هم روی CPython اجرا شود . منطقی است که موارد استفاده را جداگانه برای هر مفسر اداره کنید.استفاده از pypy برای افزایش سرعت پایتونبه پایتون 3 ارتقا دهیداگر از پایتونx.2 استفاده می کنید و دلیل موجه (مانند یک ماژول ناسازگار) ندارید ، باید ارتقا به پایتون 3 را انجام دهید ، مخصوصاً الان که پایتون 2 منسوخ شده و دیگر پشتیبانی نمی شود.گذشته از اینکه پایتون 3 به عنوان آینده زبان در نظر گرفته می شود . بسیاری از سازه ها و بهینه سازی ها در پایتون 3 در دسترس هستند که در پایتون 2.x در دسترس نیستند. به عنوان مثال ، پایتون 3.5 با قرار دادن کلمات کلیدی asyncو و awaitدر syntax زبان . برنامه نویسی ناهمگام را بسیار ساده تر می کند . Python 3.2 یک ارتقا بزرگ در Global Interpreter Lock ایجاد کرد که نحوه مدیریت Python در قسمت multi-thread را به شدت بهبود می بخشد. ?برایافزایشسرعتپایتونبهپایتون3ارتقادهید برای افزایش سرعت پایتون به پایتون 3 ارتقا دهیدتوسعه دهندگان اصلی این زبان اخیراً سایتی را راه اندازی کرده اند که ردیابی تغییرات عملکرد در نسخه های مختلف را به شما نشان می دهد.همانطور که پایتون بالغ تر می شود ، زبان های پویا و تفسیری نیز به طور کلی رشد می کنند. پس می توانید انتظار پیشرفت در فناوری کامپایلر و بهینه سازی مفسر را داشته باشید. که در نهایت باعث بهبود عملکرد پایتون در سال های پیش رو می شود.همانطور که گفته شد ، یک سیستم عامل سریع شما را فقط تا حدی جلو می برد. عملکرد هر برنامه همیشه بیشتر به شخص سازنده آن بستگی دارد تا قدرت سیستمی که آن را اجرا می کند.خوشبختانه برای عاشقان پایتون ، اکوسیستم غنی Python گزینه های زیادی به ما می دهد تا کد ما سریعتر اجرا شود. در نهایت همه می دانیم ، یک برنامه پایتون لازم نیست سریع ترین باشد .تا زمانی که می تواند در حد قابل قبولی سریع باشد.