تحليل أداء كود Swift: إيجاد نقاط الاختناق عمليًا

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا نحلل أداء كود Swift؟

\n

تطوير تطبيقات iOS و macOS لا يتطلب فقط الوظائف، بل أيضًا أداءً عاليًا. حتى أجمل كود قد يكون بطيئًا، أو يستهلك ذاكرة زائدة، أو يستنزف البطارية. تحليل الأداء هو عملية قياس أداء تطبيقك، مما يساعد في اكتشاف نقاط الاختناق (bottlenecks). في هذه المقالة، سنستعرض طرقًا عملية لتحليل أداء كود Swift باستخدام الأدوات المدمجة في Xcode ونتعلم كيفية تفسير النتائج.

\n\n

1. أدوات تحليل الأداء في Xcode: Instruments

\n

الأداة الرئيسية لتحليل أداء تطبيقات Swift هي Instruments. وهي مدمجة في Xcode وتوفر العديد من القوالب للتحليل.

\n\n

1.1. بدء تحليل الأداء

\n

لبدء التحليل، اختر في Xcode: Product → Profile (أو اضغط Cmd + I). ستفتح نافذة اختيار القالب. للبحث عن نقاط الاختناق، الأكثر استخدامًا هي:

\n
    \n
  • Time Profiler — تحليل استخدام المعالج (CPU).
  • \n
  • Allocations — تتبع تخصيص الذاكرة.
  • \n
  • Leaks — البحث عن تسربات الذاكرة.
  • \n
  • Core Animation — تحليل أداء الرسومات.
  • \n
\n\n

1.2. مثال: إيجاد دالة "ثقيلة"

\n

لنفترض أن لدينا دالة تعالج مصفوفة بيانات:

\n
func processItems(_ items: [Int]) -> [Int] {\n    var result = [Int]()\n    for item in items {\n        // محاكاة عملية ثقيلة\n        usleep(100) // 0.1 مللي ثانية\n        result.append(item * 2)\n    }\n    return result\n}
\n

شغّل Time Profiler وانتظر بضع ثوانٍ. في نافذة Instruments، سنرى أن الدالة processItems تستهلك 95% من الوقت. هذه نقطة اختناق واضحة. الحل: تسريع المعالجة (مثل استخدام DispatchQueue.concurrentPerform أو تحسين الخوارزمية).

\n\n

2. تحليل وقت التنفيذ (Time Profiler)

\n

Time Profiler هو الأداة الأكثر شيوعًا. يُظهر أي الدوال تستهلك أكبر قدر من وقت المعالج.

\n\n

2.1. قراءة النتائج

\n

بعد التحليل، سترى شجرة الاستدعاءات (Call Tree). كلما كان الشريط بجانب الدالة أوسع، زاد الوقت الذي استغرقته. انتبه إلى:

\n
    \n
  • Self — الوقت المستغرق مباشرة في هذه الدالة (بدون احتساب الدوال التي تستدعيها).
  • \n
  • Total — الوقت الإجمالي مع جميع الاستدعاءات الداخلية.
  • \n
  • Weight — النسبة المئوية من الوقت الإجمالي.
  • \n
\n\n

2.2. مثال عملي: البحث عن "تجميد" واجهة المستخدم

\n

لنفترض أن واجهة المستخدم تتجمد عند التمرير في جدول. شغّل Time Profiler وابحث عن الدالة tableView(_:cellForRowAt:). إذا كانت تستهلك أكثر من 10% من الوقت، فهذا يعني أنك تقوم بعمل زائد في الخيط الرئيسي. التحسين:

\n
// سيء: تحميل الصورة بشكل متزامن في الخيط الرئيسي\nfunc tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)\n    let imageData = try! Data(contentsOf: url) // يمنع واجهة المستخدم!\n    cell.imageView?.image = UIImage(data: imageData)\n    return cell\n}\n\n// جيد: تحميل غير متزامن\nfunc tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)\n    DispatchQueue.global().async {\n        if let imageData = try? Data(contentsOf: url) {\n            DispatchQueue.main.async {\n                cell.imageView?.image = UIImage(data: imageData)\n            }\n        }\n    }\n    return cell\n}
\n\n

3. تحليل الذاكرة (Allocations و Leaks)

\n

تسربات الذاكرة مشكلة شائعة في Swift بسبب الإغلاقات (closures) والمراجع الدائرية. تساعد Instruments في اكتشافها.

\n\n

3.1. البحث عن تس

المدونات

توصيات الكتب