مقدمة: لماذا يُعد تحليل أداء كود Swift ضرورة
يتطلب التطوير لنظامي iOS وmacOS أداءً عاليًا. حتى طريقة واحدة بطيئة يمكن أن تسبب تأخيرًا في واجهة المستخدم، أو استنزاف البطارية، أو تجميد التطبيق. تحليل أداء كود Swift هو عملية تحليل وقت التنفيذ، الذاكرة، واستخدام المعالج CPU، مما يسمح باكتشاف وإزالة نقاط الاختناق. بدون تحليل الأداء، تتحول عملية التحسين إلى تخمين: تقوم بتغيير الكود بشكل عشوائي دون معرفة ما الذي يبطئ التطبيق حقًا.
في هذه المقالة، سنستعرض الأدوات الرئيسية لتحليل أداء Swift: Xcode Instruments، os_signpost، والقياس اليدوي للوقت. ستتعلم كيفية العثور على الدوال البطيئة، تسربات الذاكرة، والخوارزميات غير الفعالة. ستكون المقالة مفيدة لكل من المبتدئين والمطورين ذوي الخبرة في iOS.
الأداة رقم 1: Xcode Instruments - مساعدك الرئيسي
Xcode Instruments هي مجموعة قوية من أدوات تحليل الأداء المدمجة في Xcode. الأداة الأكثر شهرة هي Time Profiler. وهي تظهر مقدار الوقت الذي يستهلكه المعالج CPU في كل دالة. يتم تشغيلها من خلال القائمة Product > Profile أو باستخدام اختصار Cmd + I.
كيفية استخدام Time Profiler
- قم بتشغيل تحليل أداء تطبيقك.
- نفذ الإجراء الذي يبدو بطيئًا (التمرير، تحميل البيانات، الرسوم المتحركة).
- أوقف التسجيل وانظر إلى مكدس الاستدعاءات.
- ابحث عن الدوال التي تستغرق أطول وقت تنفيذ (الأعمدة الحمراء).
مثال: إذا كانت دالة tableView(_:cellForRowAt:) تستهلك 80% من الوقت، فالمشكلة فيها. النقر المزدوج سيظهر أسطر الكود المحددة.
مثال كود لتحليل الأداء
لنفترض أن لديك دالة لتحميل الصور:
func loadImage(from url: URL) -> UIImage? { guard let data = try? Data(contentsOf: url) else { return nil } return UIImage(data: data)}سيظهر Time Profiler أن Data(contentsOf:) يحظر الخيط الرئيسي. الحل هو التحميل غير المتزامن باستخدام URLSession.
الأداة رقم 2: os_signpost - تحليل أداء موجه
أحيانًا تحتاج إلى قياس جزء واحد فقط من الكود دون إرباك ملف الأداء العام. لهذا استخدم os_signpost - واجهة برمجة تطبيقات خفيفة لوضع علامات على الأحداث. يتم إرسال البيانات تلقائيًا إلى Instruments.
إعداد os_signpost
أولاً، قم باستيراد os وإنشاء مسجل:
import os
let log = OSLog(subsystem: "com.yourapp.network", category: "Loading")ثم قم بتغليف الكود المراد قياسه:
os_signpost(.begin, log: log, name: "FetchData")// كود التحميل الخاص بكos_signpost(.end, log: log, name: "FetchData")في Instruments، اختر قالب os_signpost - سترى الوقت الدقيق لتنفيذ كل كتلة. هذا لا غنى عنه عند مقارنة خوارزميتين.
مثال واقعي: مقارنة عمليات الفرز
لنقارن الفرز القياسي والفرز اليدوي:
os_signpost(.begin, log: log, name: "SortBuiltin")let sortedBuiltin = largeArray.sorted()os_signpost(.end, log: log, name: "SortBuiltin")
os_signpost(.begin, log: log, name: "SortManual")let sortedManual = largeArray.sorted { $0 < $1 }os_signpost(.end, log: log, name: "SortManual")النتيجة غالبًا ما تكون مفاجئة: الفرز المدمج أسرع من الفرز اليدوي بنسبة 30-40%.
الأداة رقم 3: القياس اليدوي للوقت باستخدام DispatchTime
للفحوصات السريعة بدون Instruments، استخدم DispatchTime. هذه طريقة بسيطة لقياس وقت تنفيذ دالة مباشرة في الكود.
مثال على القياس
let start = DispatchTime.now()// الكتلة المراد قياسهاlet result = heavyComputation()let end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanosecondslet timeInterval = Double(nanoTime) / 1_000_000_000print("وقت التنفيذ: \\(timeInterval) ثانية")