├── Primes_cython_import.py ├── 2014.05.10_cython_tutorial.pdf ├── Primes_python.py ├── Primes_numba.py ├── Primes_cython.pyx ├── Primes_numba_parallel.py ├── benchmark.py └── README.md /Primes_cython_import.py: -------------------------------------------------------------------------------- 1 | import pyximport; pyximport.install() 2 | from Primes_cython import prime_py 3 | print(prime_py(0,100000)) -------------------------------------------------------------------------------- /2014.05.10_cython_tutorial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pythonation/python-fast-as-450million-op-in-sec/HEAD/2014.05.10_cython_tutorial.pdf -------------------------------------------------------------------------------- /Primes_python.py: -------------------------------------------------------------------------------- 1 | def prime_py(range_start, range_end): 2 | """ ـ حساب كم الأعداد الأولية الموجودة في مجال معين""" 3 | count_of_primes = 0 4 | range_start = range_start if range_start >= 2 else 2 5 | for num in prange(range_start, range_end + 1): 6 | for div_num in prange(2, num): 7 | if ((num % div_num) == 0): 8 | break 9 | else: 10 | count_of_primes += 1 11 | return count_of_primes 12 | 13 | -------------------------------------------------------------------------------- /Primes_numba.py: -------------------------------------------------------------------------------- 1 | from numba import jit 2 | 3 | @jit() 4 | def prime_py(range_start, range_end): 5 | """ ـ حساب كم الأعداد الأولية الموجودة في مجال معين""" 6 | count_of_primes = 0 7 | range_start = range_start if range_start >= 2 else 2 8 | for num in range(range_start, range_end + 1): 9 | for div_num in range(2, num): 10 | if ((num % div_num) == 0): 11 | break 12 | else: 13 | count_of_primes += 1 14 | return count_of_primes -------------------------------------------------------------------------------- /Primes_cython.pyx: -------------------------------------------------------------------------------- 1 | def prime_py(int range_start, int range_end): 2 | """ ـ حساب كم الأعداد الأولية الموجودة في مجال معين""" 3 | cdef int count_of_primes = 0 4 | cdef int num 5 | cdef int div_num 6 | 7 | range_start = range_start if range_start >= 2 else 2 8 | for num in range(range_start, range_end + 1): 9 | for div_num in range(2, num): 10 | if ((num % div_num) == 0): 11 | break 12 | else: 13 | count_of_primes += 1 14 | return count_of_primes -------------------------------------------------------------------------------- /Primes_numba_parallel.py: -------------------------------------------------------------------------------- 1 | from numba import jit , prange 2 | 3 | @jit(parallel=True) 4 | def prime_py(range_start, range_end): 5 | """ ـ حساب كم الأعداد الأولية الموجودة في مجال معين""" 6 | count_of_primes = 0 7 | range_start = range_start if range_start >= 2 else 2 8 | for num in prange(range_start, range_end + 1): 9 | for div_num in prange(2, num): 10 | if ((num % div_num) == 0): 11 | break 12 | else: 13 | count_of_primes += 1 14 | return count_of_primes -------------------------------------------------------------------------------- /benchmark.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | 3 | Cython_Code = timeit.repeat(''' 4 | prime_py(0, 100000) 5 | ''', 6 | 'import pyximport; pyximport.install(); from Primes_cython import prime_py' 7 | , repeat=3, number=1) 8 | print("Cython best time:" , min(Cython_Code) ,"Seconds ✔ OP:",455189150/min(Cython_Code)) 9 | 10 | 11 | Numba_Code = timeit.repeat(''' 12 | prime_py(0, 100000) 13 | ''', 14 | 'from Primes_numba import prime_py' 15 | , repeat=3, number=1) 16 | print("Numba best time:" , min(Numba_Code) ,"Seconds ✔ OP:",455189150/min(Numba_Code)) 17 | 18 | Numba_Prange_Code = timeit.repeat(''' 19 | prime_py(0, 100000) 20 | ''', 21 | 'from Primes_numba_parallel import prime_py' 22 | , repeat=3, number=1) 23 | print("Numba Prange best time:" , min(Numba_Prange_Code) ,"Seconds ✔ OP:",455189150/min(Numba_Prange_Code)) 24 | 25 | Python_Vanilla_Code = timeit.repeat(''' 26 | prime_py(0, 100000) 27 | ''', 28 | 'from Primes_python import prime_py' 29 | , repeat=3, number=1) 30 | print("Python best time:" , min(Python_Vanilla_Code) ,"Seconds ✔ OP:",455189150/min(Python_Vanilla_Code)) 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # بايثون بطيئة! كيف تجعلها أسرع لـ 453 مليون عملية في الثانية؟ تعلم Cython Numba PyPy الآن 2 | 3 | 4 |
11 | بايثون بطيئة!؟ وهل يمكن جعلها أسرع؟ 🤫 إليك السر! 12 | معروف أن بايثون إنها لُغةٌ سهلة التعلم، لكنها صعبةُ الإتقان وأروع لغة برمجة على الإطلاقِ. يقول البعض، ينال منها عيب خطيرٌ يُهدد وجودها ويسير بها نحو الفناء فمسألة البطء والسرعة في لغة بايثون مشكلة جليلة لا يمكن للمبرمج غض البصر عنها والبعض الآخر يراها فوق الفناء والزوال فهي وُجدت لتُحَب رغم عيوبها... ويبقى الفريقان في جدل مستمر ! 13 | كلامهم صحيح نوعا ما، إلّا أننا نستطيع جعلها أسرع لتنجز نصف مليار عملية في الثانية! 14 | 15 | جدلٌ جئنا اليوم كي نقوم بحسمه للأبد! لقد حان الوقت لوضع لغة بايثون رهن التحقيق، لإزالة الغموض عن أسوء شُبهتين وأخطرهما في عالم لغات البرمجة على الإطلاق. ألا وهما الآداءُ السيء والبطء! ! 16 | 17 | في الفيديو أعلاه، ستتعرفون عن قربٍ على التصميم الداخلي للغة بايثون: 18 | * كيف يتأثر الآداء؟ 19 | * ما الذي يحصل وراء الكواليس؟ 20 | * كيف تعمل لغة بايثون؟ 21 | * ما طبيعة العلاقة بينها وبين لغة السي؟ 22 | 23 | ونحن نجيب عن هذه الأسئلة، ستتعرفون على الـCompiler والـInterpreter وعلى الرحلة التي يقطعها كودك البرمجي ليصبح لغة الآلة ويخاطب مُعالجات الكومبيوتر، إضافة إلى الـdynamic typing(تلقائية التعرف على البيانات) والـmultiprocessing (تعدد المعالَجات)، إلى أن نجعل لغة بايثون أسرع بآلاف المرات بالإستعانة بـأي من هذه المكتبات: 24 | * Cython 25 | * Numba 26 | * PyPy 27 | 28 | وصدقنا إن أخبرناك بأن هذا الشرح سيكون صديقاً للمبتدئين beginner friendly! 29 |
30 | 31 | # كود بايثون المستخدم في الشرح 32 | 33 | ### يُفضل تحميل الأكواد الموجودة أعلاه في المستودع بدل نسحها ولصقها فأسماء الملفات مهمة. 34 | 35 | ## Vanilla Python 36 | 37 | 38 | ```python 39 | def prime_py(range_start, range_end): 40 | count_of_primes = 0 41 | range_start = range_start if range_start >= 2 else 2 42 | for num in prange(range_start, range_end + 1): 43 | for div_num in prange(2, num): 44 | if ((num % div_num) == 0): 45 | break 46 | else: 47 | count_of_primes += 1 48 | 49 | return count_of_primes 50 | ``` 51 | # فقرة استخدام Cython 52 | ### أولاً تثبيت Cython 53 | 54 | 55 |56 | بداية تثبيت حزمة cython: 57 |
58 | 59 | ## Linux/Ubuntu 60 | 61 | ```bash 62 | pip3 install cython 63 | ``` 64 | وأدوات البناء C/C++ (ضرورية) 65 | ```bash 66 | sudo apt-get install build-essential 67 | ``` 68 | [شرح مصور من اليوتيوب](https://youtu.be/GKlWmNsATFc?t=900) 69 | 70 | ## Windows 71 | 72 | ```cmd 73 | python -m pip install cython 74 | ``` 75 | 76 | يجب عليك تثبيت MinGW الذي يحتوي مترجمات لغة السي من هنا [SourceForge](https://sourceforge.net/projects/mingw/) 77 | 78 | الخطوة التالية ضرورية جداً، يجب إضافة مسار مجلد Bin من البرنامج إلى مسارات البيئة في نظام الويندوز، الأمر سهل، إذهب الى Start واكتب Environment Variables واختر هذه الأيقونة، ثم أنقر على Environment Variables، هنا في الأسفل إبحث عن متغير PATH ثم أضف إليه مسار مجلد Bin واعمل حفظ. 79 | 80 | 81 | [شرح مصور من اليوتيوب](https://youtu.be/GKlWmNsATFc?t=923) 82 | 83 | ## Mac OS 84 | 85 | ```bash 86 | pip3 install cython 87 | ``` 88 | 89 | 90 | 91 | تحميل أدوات المطورين XCode developer tools عبر 92 | تثبيت إضافة Command Line Tools 93 | يجب تثبيت xcode أولا وبعدها وافق على تنصيت الـ Command Line Tools والأمور تمام 94 | ```bash 95 | sudo xcode-select --install 96 | ``` 97 | [شرح مصور من اليوتيوب](https://youtu.be/GKlWmNsATFc?t=906) 98 | 99 | 100 | 101 | المهم بعد تثبيت مترجم لغة السي أياً كان نظام تشغيلك، قم بالتأكد من أنه يعمل عبر كتابة الأمر التالي : 102 | ```bash 103 | gcc –version 104 | ``` 105 | إذا ظهر لك اصدار المُترجِم فالأمورُ تمام. 106 | 107 | 108 | 109 |