تطوير Android / المتقدم: أنظمة محمولة وإصدارات موثوقة / الدرس 15
قياس الأداء وتشخيصه
حوّل تفاعل قائمة بطيئاً إلى فرضية قابلة للقياس ثم حسّن عنق الزجاجة المسؤول دون التضحية بالصحة.
في هذه الصفحة
أهداف الدرس
- ميّز بين كلفة البدء والإطارات والذاكرة والعمل الخلفي.
- استخدم قياسات ممثلة قريبة من الإصدار وتحسينات محددة.
عرّف التأخير الذي يراه المستخدم
يحتاج بطء البدء وتأخر النقر وتقطع التمرير وضغط الذاكرة واستنزاف البطارية أدلة مختلفة. عرّف رحلة ملموسة كفتح قائمة مخبأة وتمرير خمسين صفاً. سجل فئة الجهاز ومتغير البناء والبيانات والحرارة وحالة العملية الباردة أو الدافئة. تفيد نسخ التنقيح والمحاكيات للتحقيق لكنها قد تشوه التوقيت النهائي. يحتاج هدف الأداء طريقة قياس وتوزيع نتائج لا رقماً مثالياً واحداً. قارن ظروفاً متكافئة قبل استنتاج تحسن التجربة بتغيير الشيفرة.
اعثر على العمل المكلف في المسار الحرج
يعالج الخيط الرئيسي الإدخال وتنسيق العرض، فتؤخر عمليات القرص الحاجبة وفك الترميز والحساب الطويل الإطارات. استخدم تتبع النظام والمحلل لتحديد ما يشغل الوقت فعلياً. نقل كل شيء إلى الإدخال والإخراج ليس حلاً عاماً؛ ينتمي الحساب المكثف إلى موزع حساب مناسب ويزال العمل غير اللازم. احقن الموزعات للاختبار واحفظ صلاحية النتائج عند الإلغاء أو الاستبدال. يكشف StrictMode بعض عمل القرص والشبكة العرضي أثناء التطوير، لكنه دليل تشخيصي لا اختبار أداء كامل.
class TitleIndexer(private val compute: CoroutineDispatcher) {
suspend fun index(titles: List<String>): Map<String, List<String>> =
withContext(compute) {
titles.groupBy { it.firstOrNull()?.uppercaseChar()?.toString() ?: "#" }
}
}
احقن موزع حساب مناسباً مثل Dispatchers.Default من جذر التركيب وموزع اختبار في الاختبارات. سياسة التجميع بسيطة قصداً وليست فهرسة لغوية كاملة. يبرر النقل عندما يثبت القياس أهمية حجم العمل.
قِس التركيب والتخطيط والرسم منفصلة
ليست إعادة التركيب عيب أداء تلقائياً. افحص تكرار الحساب المكلف والمدخلات غير الثابتة والعمل غير اللازم، أو سيطرة التخطيط والرسم بدلاً منهما. تحفظ مفاتيح القائمة الثابتة الهوية وتساعد أنواع المحتوى المناسبة إعادة الاستخدام. فك الصور بحجم مناسب للعرض واستخدم محمّل صور يراعي دورة الحياة بدلاً من صور كاملة الدقة بكل صف. لا تصف الأنواع بأنها immutable إلا إذا صح الوعد. يعتمد تجاوز المترجم على أدوات Compose المختارة، فافحص تقاريرها والتتبعات بدلاً من تطبيق أفكار قديمة عشوائياً.
علّم المراحل ذات المعنى
تربط مقاطع التتبع عملية التطبيق بخط النظام الزمني دون سجلات مطولة في مسار ساخن. اجعلها قصيرة واقرن البدء والنهاية بكتلة finally وتجنب البيانات الشخصية في العناوين. قد يكشف مقطع حول تحويل متزامن سيطرة فك الترميز أو الفرز على التحديث. لا تمدد مقطعاً مرتبطاً بخيط عبر تعليق coroutine اعتباطي؛ استخدم واجهة تتبع غير متزامن مدعومة. اربط العلامات بفقد الإطارات ونشاط القاعدة والجدولة قبل اختيار موضع التحسين.
fun sortedTitles(titles: List<String>): List<String> {
Trace.beginSection("reading-sort")
return try {
titles.sorted()
} finally {
Trace.endSection()
}
}
استورد android.os.Trace واستدعِه من مسار تطبيق مقاس. لا يحتوي العنوان نص مستخدم. الدالة متزامنة فيعمل beginSection وendSection على الخيط نفسه؛ لا تدخل استدعاء تعليق داخل الغلاف.
تحقق من التحسين وملكية الذاكرة
يقيس Macrobenchmark رحلات المستخدم كالبدء والتمرير بظروف مضبوطة، وتعزل القياسات المصغرة عمليات أصغر. قد تحسن Baseline Profiles مسارات مهمة لكن يجب توليدها والتحقق منها لرحلات ممثلة، ولا تعوض خوارزميات كفؤة. افحص الأنشطة المحتفظ بها والمخابئ الضخمة والمجموعات غير المحدودة عند نمو الذاكرة. التسرب احتفاظ غير مرغوب، بينما يحتاج مخبأ كبير محدود مقصود تحليلاً مختلفاً. أعد الرحلة الأصلية بعد التغيير وتحقق من بقاء الصحة والوصول واستهلاك الموارد مقبولاً قبل قبول رقم أسرع.
الأخطاء الشائعة وإصلاحها
يختفي تحسن مزعوم في الإصدار
- لماذا يحدث؟
- قيس توقيت تنقيح أو تشغيلات غير متكافئة فقط.
- كيف تصلحه؟
- استخدم ظروف قياس متكافئة قريبة من الإصدار.
- كيف تتجنب تكراره؟
- سجل البيانات والجهاز وحالة العملية مع النتائج.
تنمو الذاكرة بعد كل تدوير
- لماذا يحدث؟
- يحتفظ كائن طويل العمر بأنشطة قديمة.
- كيف تصلحه؟
- أزل المرجع أو استخدم المالك الصحيح المحدد بدورة الحياة.
- كيف تتجنب تكراره؟
- افحص الملكية قبل إضافة singleton أو دوال رد.
يجعل التحسين الصفوف تعرض محتوى قديماً
- لماذا يحدث؟
- تمنع افتراضات ثبات أو تخزين مؤقت خاطئة تحديثات لازمة.
- كيف تصلحه؟
- أعد عقود حالة صادقة وخزّن حسب الهوية الكاملة.
- كيف تتجنب تكراره؟
- اقرن فحوص الأداء بسيناريوهات الصحة.
اختبر فهمك
1. يفقد التمرير إطارات مع انخفاض عدد إعادة التركيب. ما التحقيق التالي؟
اعرض الحل المشروح
افحص تتبع الإطارات للتخطيط والرسم وفك الصور وجمع الذاكرة والحجب الرئيسي. لا يعني انخفاض إعادة التركيب إطارات رخيصة. استخدم البيانات والنافذة نفسيهما وحدد المرحلة المسيطرة وغير عنق زجاجة مقاساً واحداً ثم أعد المقارنة.
2. يحسن مخبأ البدء لكنه يحتفظ بكل غلاف للأبد. اقترح سياسة محدودة وتحققاً.
اعرض الحل المشروح
ضع حدود ذاكرة وقرص صريحة مع إخلاء مناسب للأصول القابلة لإعادة الإنشاء. احفظ صوراً مناسبة للعرض في الذاكرة وتجنب مراجع الأنشطة. قِس تصفحاً متكرراً يتجاوز الحد وتحقق من استقرار الذاكرة وإعادة تحميل الأصول دون فقد محتوى فريد.
أهم ما تعلمته
- يبدأ الأداء برحلة مستخدم قابلة للتكرار.
- تتبّع المرحلة المسؤولة قبل التحسين.
- يحفظ التحسن المفيد الصحة وحدود استهلاك الموارد.