NumPy: تحسين الأداء

آخر تحديث: 2026-08-26

1. ما ستتعلمه




2. المفاهيم الأساسية

(1) المتجهة

PYTHON
import numpy as np
import time

n = 10_000_000
a = np.random.rand(n)
b = np.random.rand(n)

# بطيء: حلقة Python
t0 = time.time()
c = np.empty(n)
for i in range(n):
    c[i] = a[i] + b[i]
t1 = time.time()

---
## 3. سريع: مُتجه
t2 = time.time()
d = a + b
t3 = time.time()

print(f"Loop: {t1-t0:.3f}s, Vectorized: {t3-t2:.6f}s")
print(f"Speedup: {(t1-t0)/(t3-t2):.0f}x")

(2) العمليات في المكان

PYTHON
---
## 4. تجنب النسخ باستخدام معامل out=
a = np.random.rand(1000000)
b = np.random.rand(1000000)

---
## 5. نسخ (يخصص ذاكرة جديدة)
c = a + b

---
## 6. في المكان (لا تخصيص)
np.add(a, b, out=a)

▶ مثال: مقارنة سرعة المتجهة (الصعوبة ⭐⭐)

PYTHON
import numpy as np
import time

n = 1_000_000
a = np.random.rand(n)
b = np.random.rand(n)

---
## 7. بطيء: حلقة Python
t0 = time.time()
c = np.empty(n)
for i in range(n):
    c[i] = a[i] + b[i]
t1 = time.time()

---
## 8. سريع: مُتجه
t2 = time.time()
d = a + b
t3 = time.time()

loop_time = t1 - t0
vec_time = t3 - t2
print(f"Loop: {loop_time:.3f}s, Vectorized: {vec_time:.6f}s")
print(f"Speedup: {loop_time/vec_time:.0f}x")

المخرجات:

TEXT 📖 للعرض فقط
# تم التنفيذ بنجاح

المخرجات:

TEXT 📖 للعرض فقط
Loop: 0.312s, Vectorized: 0.002s
Speedup: 156x

▶ مثال: العمليات في المكان باستخدام out= (الصعوبة ⭐⭐)

PYTHON
import numpy as np

a = np.array([10, 20, 30, 40, 50])
b = np.array([1, 2, 3, 4, 5])

---
## 9. بدون out: ينشئ مصفوفة جديدة
c = np.add(a, b)
print("Without out:", c)

---
## 10. مع out: يعيد استخدام الذاكرة الموجودة
result = np.empty(5)
np.add(a, b, out=result)
print("With out:", result)

---
## 11. تسلسل العمليات في المكان
np.multiply(result, 2, out=result)
np.add(result, 1, out=result)
print("Chained:", result)

المخرجات:

TEXT 📖 للعرض فقط
Without out:
With out:
Chained:

المخرجات:

TEXT 📖 للعرض فقط
Without out: [11 22 33 44 55]
With out: [11 22 33 44 55]
Chained: [23 45 67 89 111]

▶ مثال: تأثير تخطيط الذاكرة (الصعوبة ⭐)

PYTHON
import numpy as np

---
## 12. C-contiguous (صف-رئيسي) — الافتراضي
c = np.array([[1, 2, 3], [4, 5, 6]])
print("C-contiguous:", c.flags.c_contiguous)
print("Fortran-contiguous:", c.flags.f_contiguous)

---
## 13. تحويل إلى Fortran-contiguous (عمود-رئيسي)
f = np.asfortranarray(c)
print("Fortran-contiguous:", f.flags.f_contiguous)

---
## 14. الشكل والخطوات
print("C strides:", c.strides)
print("F strides:", f.strides)

المخرجات:

TEXT 📖 للعرض فقط
C-contiguous:
Fortran-contiguous:
Fortran-contiguous:
C strides:
F strides:

المخرجات:

TEXT 📖 للعرض فقط
C-contiguous: True
Fortran-contiguous: False
Fortran-contiguous: True
C strides: (24, 8)
F strides: (8, 24)



❓ أسئلة شائعة

س ما هي أهم قاعدة أداء واحدة؟
ج تجنب حلقات Python. كل مرة تكتب فيها for i in range(n)، اسأل: "هل يمكنني جعلها مُتجهة؟" إذا كانت الإجابة نعم، سيكون NumPy أسرع بـ 10-100 مرة.
س ما الفرق بين ترتيب C وترتيب Fortran؟
ج ترتيب C (صف-رئيسي) يخزن الصفوف بشكل متجاور. ترتيب Fortran (عمود-رئيسي) يخزن الأعمدة بشكل متجاور. استخدم الترتيب الذي يتناسب مع نمط وصولك للحصول على أفضل أداء للذاكرة المؤقتة.
س متى يجب استخدام معامل out=؟
ج عندما تقوم بالعديد من العمليات على نفس المصفوفة الكبيرة، out= يتجنب تخصيص ذاكرة جديدة لكل عملية. استخدمه في الحلقات وخطوط الأنابيب.

📖 ملخص



📝 تمارين

  1. مبتدئ (الصعوبة ⭐): قارن الوقت اللازم لحساب a + b لـ 10 ملايين عنصر باستخدام حلقة مقابل المتجهة. سجّل عامل التسريع.

  2. متوسط (الصعوبة ⭐⭐): قارن وقت a + b مع وبدون out=a. قس الفرق في overhead التخصيص.

  3. متقدم (الصعوبة ⭐⭐⭐): أنشئ مصفوفة كبيرة، حولها، ثم اجمع على طول محور. قارن أداء المصفوفة المحولة مقابل نسخة متجاورة. اشرح الفرق.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%