سایتون (Cython) توسعه داده شده است تا امکان ساخت افزونههای C را برای پایتون سادهتر کند و به کدهای موجود پایتون اجازه دهد تا به C تبدیل شوند. علاوه بر این، سایتون این امکان را برای کدهای بهینه شده فراهم میکند تا بدون وابستگیهای خارجی با پایتون همراه شوند.
در این مقاله ما مراحلی را که لازم است تا کدهای موجود پایتون به سایتون تبدیل شده و در یک اپلیکیشن کاربردی مورد استفاده قرار گیرند، بررسی خواهیم کرد.
یک مثال از سایتون
اجازه دهید در ابتدا با یک مثال ساده که از اسناد سایتون گرفته شده کار را آغاز کنیم، یک پیاده سازی نه چندان کارآمد از یک تابع انتگرال:
def f(x):
return x**2-x
def integrate_f(a, b, N):
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx
خواندن و درک این کد راحت است، اما اجرای آن به کندی صورت میگیرد. این به دلیل آن است که پایتون باید به طور دائم بین انواع شیهای خود و انواع مقادیر عددی ماشین در رفت و آمد باشد.
حالا نسخه سایتون همین کد را در نظر بگیرید که در اینجا زیر بخشهای اضافه شده سایتون خط کشیده شده است:
cdef f(double x):
return x**2-x
def integrate_f(double a, double b, int N):
cdef int i
cdef double s, x, dx
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx
این بخشهای اضافی به ما اجازه میدهد در میان این کد صریحا انواعی از متغیرها را تعریف کنیم، به این شكل کامپایلر سایتون میتواند این بخشهای اضافه را به C تفسیر کند.
کدهای دستوری سایتون
کلمات کلیدی که برای الصاق کدهای سایتون مورد استفاده قرار میگیرد، در کدهای دستوری معمول پایتون پیدا نمیشود. آنها منحصرا برای سایتون توسعه داده شدهاند، بنابراین وقتی این فرامین به یک کد اضافه میشوند نمیتوان آنها را به شکل یک برنامه پایتون معمولی اجرا کرد.
اینها رایجترین عناصر موجود در کدهای دستوری سایتون هستند:
نوع متغیرها
بعضی از انواع متغیرهایی که در سایتون استفاده میشوند، از خود متغیرهای پایتون مثل int, float و long اقتباس شدهاند. سایر انواع متغیرهای سایتون نیز در C پیدا میشوند، مثل char یا struct، بعضی نیز به صورت unsigned long تعریف میشوند. باقی آنها نیز مثل bint مخصوص خود سایتون هستند.
نوع توابع cdef و cpdef
کلیدواژه cdef استفاده از نوع سایتون یا C را مشخص میکند. همچنین از آن برای تعریف توابعی که شما مایلید در پایتون داشته باشید، استفاده میشود.
توابعی که در سایتون با استفاده از کلیدواژه پایتون def نوشته میشوند برای سایر کدهای پایتون قابل دسترس هستند، اما با محدودیتهای وضعیت عملکرد پایتون مواجه میشوند. توابعی که از کلیدواژه cdef استفاده میکنند تنها برای سایر کدهای سایتون و C قابل دسترس هستند، اما خیلی سریعتر اجرا میشوند. اگر شما توابعی دارید که تنها به صورت داخلی در خود ماژول سایتون فراخوانی میشوند، از cdef استفاده کنید.
سومین کلیدواژه cpdef است که امکان سازگاری با کدهای پایتون و کدهای C را به شیوهای که کدهای C میتوانند با حداکثر سرعت به این تابع دسترسی داشته باشد فراهم میکند. هر چند این سهولت در کار پیامدهایی را نیز در پی دارد: توابع cpdef کدهای بیشتری تولید میکنند و نسبت به cdef فراخوانی آنها منابع بیشتری نیاز دارد.
سایر کلیدواژههای سایتون سایر کلمات کلیدی در سایتون کنترل جنبههای مختلف چرخه برنامه را که در پایتون وجود ندارد، برعهده دارند:
• Gil و nogil مدیریت منابعی را برعهده دارند که برای معین کردن بخشهایی از کد که به Global Interpreter Lock پایتون نیاز دارد (با gil:) یا نیاز ندارد (با nogil:) استفاده میشود. کدهای C که هیچ فراخوانی به API پایتون ندارند، در یک بلوک nogil سریعتر اجرا میشوند، به ویژه اگر یک عملیات طولانی را اجرا کنند.
• از cimport برای نظارت بر ورود نوع داده، تابع، متغیرها و نوع افزونه C به سایتون استفاده میشود. برای نمونه، اپلیکیشنهای سایتون که از ماژول NumPy اصلی C استفاده میکنند، از cimport برای فراهم کردن امکان دسترسی به این توابع استفاده میکنند.
• Include کد منبع یک فایل سایتون را به همان شیوه موجود در C به کدهای دیگر اضافه میکند. توجه داشته باشید كه سایتون از یک روش پیچیدهتری برای اشتراک گذاشتن عبارات بین فایلهای سایتون نسبت به include استفاده میکند.
• از ctypedef برای ارجاع به هدر فایلهای خارجی C استفاده میشود.
• از Extern با cdef استفاده میشود تا به توابع C یا متغیرهای پیدا شده در سایر ماژولها مراجعه کند.
• از public/api استفاده میشود تا عباراتی را در ماژولهای سایتون ایجاد کند که میتوان در سایر کدهای C به آن دسترسی داشت.
• از inline استفاده میشود تا یک تابع را به صورت خطی تعریف کرد، و یا کدهای آن را به منظور افزایش سرعت در بدنه تابع فراخوانی شده به کار گرفت. برای نمونه تابع f در کد مثال بالا میتواند به inline مجهز شود تا سرعت فراخوانی را افزایش دهد، زیرا از آن تنها در یک مکان استفاده میشود.
نیازی نیست که پیشاپیش از تمام کلمات کلیدی سایتون آگاه باشید. کدهای سایتون به شکلی در نظر گرفته شدهاند که میتوان آنها را به تدریج نوشت. ابتدا شما کد پایتون را مینویسید، سپس ضمایم سایتون را به منظور افزایش سرعت به آن اضافه میکنید. به این شكل شما میتوانید به تدریج کلیدواژه فرامین دستوری سایتون را برداشته و بر اساس نیاز خود استفاده کنید.
کامپایل سایتون
حالا که با نحوه عملکرد یک برنامه ساده سایتون آشنا شدید، در ادامه قصد داریم مراحل مورد نیاز را برای کامپایل سایتون به یک فایل باینری قابل اجرا بررسی کنیم.
برای ساخت یک برنامه قابل اجرای سایتون ما به سه چیز نیاز خواهیم داشت:
1. مفسر پایتون، در صورت امکان از آخرین نسخه منتشر شده استفاده کنید.
2. بسته سایتون، شما میتوانید با استفاده از روش مدیر پکیج pip به صورت pip install cython سایتون را به پایتون اضافه کنید.
3. یک کامپایلر C
اگر شما از ویندوز مایکروسافت به عنوان پلتفرم توسعه خود استفاده میکنید باید گزینه شماره 3 را مد نظر داشته باشید. برخلاف لینوکس، ویندوز به عنوان یک تجهیزات استاندارد به کامپایلر C مجهز نیست. برای دستیابی به این ویژگی یک کپی از Microsoft Visual Studio Community Edition انتخاب کنید که با کامپایلر C مایکروسافت همراه است و هزینهای برای شما به همراه ندارد.
برنامههای سایتون از پسوند فایل .pyx استفاده میکنند. در یک دایرکتوری جدید یک فایل به نام num.pyx ایجاد کنید که شامل کد سایتون نمایش داده شده در مثال بالا است و یک فایل دیگر به نام
main.py بسازید که شامل کد زیر است:
from num import integrate_f
print (integrate_f(1.0, 10.0, 2000))
این یک برنامه عادی پایتون است که تابع integrate_f موجود در num.pyx را فراخوانی میکند. کد پایتون با کد سایتون تنها به شکل یک ماژول دیگر برخورد میکند، بنابراین شما به جز وارد کردن این ماژول کامپایل شده و اجرای توابع آن نیاز نیست کار خاص دیگری انجام دهید.
سرانجام، یک فایل دیگر با نام setup.py با کد زیر اضافه کنید:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules = [
Extension(
r’num’,
[r’num.pyx’]
),
]
setup(
name=’num’,
ext_modules=cythonize(ext_modules),
)
setup.py در حالت عادی توسط پایتون برای نصب ماژول همراه با آن استفاده میشود و همچنین میتوان از آن برای کامپایل مستقیم افزونههای C در پایتون استفاده کرد. در اینجا ما از setup.py برای کامپایل کدهای سایتون استفاده میکنیم.
اگر شما از لینوکس استفاده میکنید و یک کامپایلر C نصب شده دارید میتوانید فایل .pyx را با اجرای این فرمان به C کامپایل کنید:
> python setup.py build_ext --inplace
اگر از ویندوز استفاده میکنید باید یک فایل بچ به نام compile.bat اضافه کنید تا فرآيند کامپایل را خودکارسازی کند:
@SETLOCAL
set DISTUTILS_USE_SDK=1
call “C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat” amd64
python setup.py build_ext --inplace --compiler=msvc
توجه داشته باشید كه مسیر درست به vcvarsall.bat در خط 3 به نسخه ویژوال استودیو که شما نصب کردهاید، بستگی دارد. فرض این مثال بر این است که شما از Visual Studio 2017 Community استفاده کردهاید.
اگر عمل کامپایل با موفقیت انجام شود، شما باید فایلهای جدیدی را در این دایرکتوری مشاهده کنید: num.c (فایل C تولید شده توسط سایتون) و یک فایل با پسوند .o (در لینوکس ) یا .pyd (در ویندوز). این همان فایل باینری است که فایل C به آن کامپایل شده است. شما ممکن است یک دایرکتوری به نام \build را نیز مشاهده کنید که شامل مصنوعاتی از فرآیند ساخت است.
فرمان python main.py را اجرا کنید تا به عنوان پاسخ برگشتی چیزی شبیه به این را مشاهده کنید:
283.297530375
این همان خروجی تابع انتگرال کامپایل شده که توسط کد اصلی پایتون ما فراخوانی شده است. با پارامترهای این تابع در main.py بازی کنید تا ببینید این خروجی چگونه تغییر میکند.
توجه داشته باشید هر زمان که شما تغییراتی را به فایل .pyx اعمال میکنید باید آن را دوباره کامپایل کنید. مسلما هر تغییری که شما روی کدهای معمول پایتون اعمال کنید فورا تاثیرگذار خواهد بود.
نتیجه فایل کامپایل شده هیچ وابستگی بجز نسخه پایتونی که برای آن کامپایل شده ندارد و به همین دلیل میتوان آن را به یک binary wheel الصاق کرد. توجه داشته باشید كه اگر شما در کد خود به سایر کتابخانهها مثل NumPy (در ادامه به آن خواهیم پرداخت) ارجاع داشته باشید باید آنها را به عنوان بخشی از عناصر مورد نیاز اپلیکیشن خود فراهم کنید.
چگونه از سایتون استفاده کنیم
حالا که متوجه شدیم چگونه میتوان یک کد را به سایتون تبدیل کرد، مرحله بعدی این است که ببینیم چگونه اپلیکیشن پایتون شما میتواند از مزایای سایتون استفاده کند. و دقیقا کجا باید آن را به کار بگیرید؟
برای دریافت نتیجه بهتر، از سایتون برای بهینه سازی این نوع از توابع پایتون استفاده کنید:
• توابعی که در چرخههای فشرده اجرا میشوند یا در یک بخش مهم و حیاتی از یک کد نیاز به مقدار زیادی زمان پردازش دارند.
• توابعی که به انجام اعمال عددی میپردازند.
• توابعی که با شیهایی کار میکنند که در زبان C وجود دارند. مثل انواع عددی، آرایهها یا ساختارها به جای انواع شیهای پایتون مثل لیستها، دیکشنریها یا تاپلها.
پایتون نسبت به سایر زبانهای غیر تفسیری اصولا در چرخهها و انجام اعمال عددی کارایی پایینتری دارد. هر چه شما بیشتر از انواع عددی تبدیل شده به C در کد خود استفاده کنید، محاسبات عددی سریعتر انجام خواهد شد.
استفاده از انواع شیهای پایتون در سایتون به خودی خود مشکلساز نیست. توابع سایتون که از شیهای پایتون استفاده میکنند همچنان کامپایل میشوند و زمانی که عملکرد اولويت اصلی نیست شیهای پایتون ترجيح داده میشوند. اما هر کدی که از شیهای پایتون استفاده میکند با مشکلات عملکرد ذاتی پایتون مواجه میشود زیرا سایتون کدها را مستقیم بر اساس API و ABIهای پایتون تولید خواهد کرد.
یکی دیگر از اهداف ارزشمند بهینهسازی با سایتون کدهای پایتونی است که مستقیم با یک کتابخانه C در تعامل است. شما میتوانید از کد wrapper پایتون صرف نظر کرده و مستقیم با کتابخانهها در ارتباط باشید.
اما سایتون نمیتواند به طور خودکار فراخوانی مناسب را برای ارتباط با این کتابخانهها توليد کند. شما باید سایتون را به شکلی تنظیم کنید که در هدر فایلهای کتابخانهها به توابع ارجاع داده شود. روش انجام این کار استفاده از دستور cdef extern from است.
یکی از کتابخانههای خارجی C که سایتون میتواند مستقیم از آن استفاده کند NumPy است. برای بهرهمند شدن از دسترسی سريع سایتون به آرایههای NumPy از cimport numpy استفاده کنید و سپس از دستورالعملهای cdef برای مشخص کردن متغیرهای NumPy از قبیل cdef np.array یا np.ndarray استفاده کنید.
نمایهسازی سایتون
اولین مرحله برای ارتقای عملکرد یک اپلیکیشن نمایه (profile) کردن آن برای تولید یک گزارش دقیق از جایی است که زمان در طی اجرای اپلیکیشن صرف میشود. برای این کار پایتون یکسری مکانیزمهای داخلی را برای توليد کد نمایهها ارائه میکند. سایتون نه تنها میتواند از این مکانیزمها استفاده کند، بلکه ابزار نمایه سازی اختصاصی خود را نیز دارد. cProfile نمایه ساز خود پایتون است که گزارشهایی را از بیشترین زمان مصرفی توسط توابع را در یک برنامه پایتون توليد میکند.
در حالت پیش فرض کدهای سایتون در این گزارشها نمایش داده نمیشوند اما شما میتوانید با وارد کردن یک دستورالعمل کامپایلر در بالای فایل .pyx به همراه توابعی که میخواهید در نمایهسازی شما حضور داشته باشد نمایهسازی کدهای سایتون را فعال کنید :
# cython: profile=True
سایتون همچنین میتواند گزارشهایی مبنی بر میزان تبدیل شدن فایل .pyx به C و میزان کدهای باقی مانده پایتون را نیز تولید کند. برای انجام این کار فایل setup.py مثال خود را باز میکنیم و دو خط زیر را به بالای آن اضافه میکنیم:
import Cython.Compiler.Options
Cython.Compiler.Options.annotate = True
حالا فایلهای .c تولید شده در این پروژه را پاک کنید و برای کامپایل دوباره همه چیز اسکریپت setup.py را دوباره اجرا کنید. بعد از انجام این کار شما یک فایل HTML (در مثال ما num.html) را در همان دایرکتوری که فایل .pyx قرار دارد، مشاهده خواهید کرد. فایل HTML را باز کنید تا بخشهایی از کد خود را که همچنان به پایتون وابسته است با هایلایت زرد رنگ مشاهده کنید. با کلیک روی نواحی زرد رنگ کدهای C تولید شده توسط سایتون را مشاهده خواهید کرد. (شکل یک)
در این مورد تابع cdef f با وجود داشتن یک تابع cdef و متغیر آن که به وضوح تایپ شده، همچنان با رنگ زرد هایلایت شده است. این به دلیل آن است که مقدار بازگشتی این تابع تایپ نشده است. سایتون فرض را بر این میگذارد که این تابع به جای یک double، یک شی پایتون را بازمیگرداند، به همین دلیل کد API پایتون را برای اداره آن تولید میکند.
ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را میتوانید از کتابخانههای عمومی سراسر کشور و نیز از دکههای روزنامهفروشی تهیه نمائید.
ثبت اشتراک نسخه کاغذی ماهنامه شبکه
ثبت اشتراک نسخه آنلاین
کتاب الکترونیک +Network راهنمای شبکهها
- برای دانلود تنها کتاب کامل ترجمه فارسی +Network اینجا کلیک کنید.
کتاب الکترونیک دوره مقدماتی آموزش پایتون
- اگر قصد یادگیری برنامهنویسی را دارید ولی هیچ پیشزمینهای ندارید اینجا کلیک کنید.
نظر شما چیست؟