لقد وضعنا أيدينا على Cythona ، بفضل العزلة الذاتية. المشكلة معقدة - كيفية الإسراع في لغة بيثون بأقل خسارة في بناء الجملة. أحد الأساليب هو استخدام Cython (خليط من C و python). المنشور بعنوان بصوت عال
مسكون . لكن يمكن تعلم القليل من محتوى المنشور ، لأن الصيغ والجدول الناتج غير صحيحين. دعنا نحاول إكمال الصورة التي بدأها مؤلفو المنشور ونضع علامة على و.
* تم إجراء الاختبارات على odroid xu4 و ubuntu mate و python 2.7.17.
Cython سهل التثبيت (pip install cython).
سوف نعذب جميع أرقام فيبوناتشي نفسها. لنقم بإنشاء ملفات لاختبارات كسب الأداء. للغة بيثون (test.py):
def test(n):
a, b = 0.0, 1.0
for i in range(n):
a, b = a + b, a
print (a)
للغة السيثون (test2.pyx):
def test2(int n):
cdef int i
cdef double a=0.0, b=1.0
for i in range(n):
a, b = a + b, a
print (a)
يتطلب ملف cython إنشاء مسبق. لنقم بإنشاء ملف setup.py له بالمحتوى التالي:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize('test2.pyx'))
واجمع:
python setup.py build_ext --inplace
الآن لنأخذ الملف من المنشور المذكور مع الاختبارات ونصلحه قليلاً عن طريق إضافة القدرة على إدخال رقمك الخاص في البداية (test.py):
import test
import test2
import time
number = input('enter number: ')
start = time.time()
test.test(number)
end = time.time()
py_time = end - start
print("Python time = {}".format(py_time))
start = time.time()
test2.test(number)
end = time.time()
cy_time = end - start
print("Cython time = {}".format(cy_time))
print("Speedup = {}".format(py_time / cy_time))
دعونا نرى ما حدث:
python tests.py
النتائج:
بالنسبة للبايثون 2.7:
enter number: 10
Python time = 1.62124633789e-05
Cython time = 4.05311584473e-06
Speedup = 4.0
enter number: 100
Python time = 3.40938568115e-05
Cython time = 5.00679016113e-06
Speedup = 6.80952380952
enter number: 1000
Python time = 0.000224113464355
Cython time = 1.19209289551e-05
Speedup = 18.8
enter number: 100000
Python time = 0.0200171470642
Cython time = 0.000855922698975
Speedup = 23.3866295265
بالنسبة إلى Python 3:
enter number: 10
Python time = 7.653236389160156e-05
Cython time = 2.8133392333984375e-05
Speedup = 2.7203389830508473
enter number: 100
Python time = 8.678436279296875e-05
Cython time = 3.170967102050781e-05
Speedup = 2.736842105263158
enter number: 1000
Python time = 0.00031876564025878906
Cython time = 4.673004150390625e-05
Speedup = 6.821428571428571
enter number: 100000
Python time = 0.01643967628479004
Cython time = 0.0004260540008544922
Speedup = 38.5858981533296
* تم "إعادة بناء" وحدة test2.pyx باستخدام الأمر:
python3 setup.py build_ext --inplace
** تم تثبيته بواسطة cython:
pip3 install cython
يمكنك الاستغناء عن إنشاء test2.pyx باستخدام setup.py ، لذلك تحتاج فقط إلى إضافة الأسطر إلى ملف test.py :
import pyximport
pyximport.install()
الآن سيتم إنشاء test2.pyx بسرعة في كل مرة يتم فيها تشغيل test.py ، وستكون هناك ملفات أقل في المجلد.
كيفية الحصول على السيثون على الويندوز.
على الرغم من حقيقة أن cython يسمح بتجميع الملفات لكل من python3 و python2 ،
مع python3 ، يعمل أمر الإنشاء:
python setup.py build_ext -i --compiler=msvc
ومع ذلك ، لعمله الكامل ، تحتاج إلى تثبيت جزء من مكونات visual studio 2019. ما يجب تثبيته موضح في الحل هنا .
لذلك ، هناك خياران للعمل يتيحان لك العمل (إنشاء ملف) في windows باستخدام cython.
الأول يستخدم python2.7 والمترجم mingw.
الإجراء على النحو التالي.
1- ثبِّت cython نفسه تحت python2.7:
py -2 -m pip install cython
2. قم بتثبيت برنامج التحويل البرمجي mingw:
mingw
3. بعد تثبيت المترجم وإضافته إلى نوافذ PATH ، يمكن تجميع ملف .pyx باستخدام الأمر:
python setup.py build_ext -i --compiler=mingw32
والثاني هو استخدام python3.x ومترجم msvc.
كيفية تشغيل cython في دفتر jupyter.
في بعض الأحيان يكون من الضروري اختبار عمل الكود بصريًا باستخدام jupyter. من أجل عدم تجميع الكود في cmd في كل مرة ، يمكنك استخدام cython مباشرة في خلايا jupyter.
للقيام بذلك ، قم باستيراد cython عن طريق التنفيذ في خلية jupyter:
%load_ext cython
ودعنا ننفذ بعض التعليمات البرمجية في الخلية التالية:
%%cython -a
import numpy as np
cdef int max(int a, int b):
return a if a > b else b
cdef int chebyshev(int x1, int y1, int x2, int y2):
return max(abs(x1 - x2), abs(y1 - y2))
def c_benchmark():
a = np.random.rand(1000, 2)
b = np.random.rand(1000, 2)
for x1, y1 in a:
for x2, y2 in b:
chebyshev(x1, x2, y1, y2)
إذا نجح كل شيء ، فسيكون الإخراج كما يلي:
