قياس الأداء
أدوات تحليل الأداء والتتبعات والاختبارات المعيارية
قياس الأداء درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 4 دروس في المجموع.
قِس قبل أن تحسّن
القاعدة الذهبية للعمل على الأداء: قِس أولًا، ولا تخمّن أبدًا. فالحدس البشري بشأن ما هو بطيء يكون خاطئًا في معظم الأحيان.
ستتعلم في هذا الدرس الأدوات التي يوفرها Android لرؤية الأداء: أدوات التحليل، وتتبع النظام، والاختبارات المعيارية المصغرة. وبمجرد أن تتمكن من القياس، يصبح كل تحسين قرارًا يستند إلى البيانات بدلًا من كونه مجرد حدس.
- تعرض أدوات التحليل استخدام وحدة المعالجة المركزية والذاكرة والطاقة في الوقت الفعلي.
- تكشف آثار النظام بالضبط عن كيفية توزيع وقت كل إطار.
- توفر الاختبارات المعيارية أرقامًا قابلة للتكرار يمكنك مقارنتها بين عمليات البناء.
ميزانية الإطار البالغة 16ms
على شاشة بتردد 60Hz، يرسم النظام إطارًا جديدًا كل 16.67ms. إذا تعذر على تطبيقك تجهيز إطار خلال هذه المهلة، يُسقط الإطار ويلاحظ المستخدمون التقطّع (التأتأة). وعلى الأجهزة ذات التردد 120Hz، تنخفض الميزانية إلى نحو 8ms.
يتعلق العمل على الأداء فعليًا بالبقاء ضمن هذه الميزانية. يوضح التعليق أدناه الحساب الذي ينبغي أن تضعه في ذهنك باستمرار.
// Frame budget math
// 60 Hz -> 1000ms / 60 = 16.67ms per frame
// 90 Hz -> 1000ms / 90 = 11.11ms per frame
// 120 Hz -> 1000ms / 120 = 8.33ms per frame
//
// Exceed the budget on the UI thread = a dropped frame = visible jank.
fun frameBudgetMs(refreshHz: Int): Double = 1000.0 / refreshHz
fun main() {
println("60Hz -> %.2f ms".format(frameBudgetMs(60)))
println("120Hz -> %.2f ms".format(frameBudgetMs(120)))
}أداة تحليل الأداء في Android Studio
ترتبط أداة تحليل الأداء في Android Studio (View > Tool Windows > Profiler) بتطبيق قيد التشغيل، وتعرض مخططات زمنية مباشرة لوحدة المعالجة المركزية والذاكرة والطاقة والشبكة.
- CPU: سجّل تتبعات الأساليب وتتبعات النظام للعثور على مسارات التعليمات البرمجية التي تستهلك معظم الوقت.
- Memory: راقب عمليات التخصيص والتقط تفريغات الكومة للعثور على التسريبات.
- Energy: اكتشف أقفال الاستيقاظ والمهام المفرطة التي تستنزف البطارية.
استخدم دائمًا إصدارًا مماثلًا لإصدار الإنتاج على جهاز حقيقي. تعطي إصدارات التصحيح والمحاكيات أرقامًا مضللة لأن التحسينات تكون معطلة.
Macrobenchmark للسيناريوهات الفعلية
تقيس مكتبة Jetpack Macrobenchmark رحلات المستخدم الكاملة (بدء التشغيل والتمرير والتنقل) على جهاز حقيقي، وتقدم مقاييس مستقرة مثل توقيت الإطارات ووقت بدء التشغيل.
تكتب اختبارًا يشغّل تطبيقك وينفّذ مسارًا معينًا؛ ثم تشغّله المكتبة مرات عديدة وتمنحك قيم الوسيط والمئين 99.
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
@get:Rule val rule = MacrobenchmarkRule()
@Test
fun coldStartup() = rule.measureRepeated(
packageName = "com.example.app",
metrics = listOf(StartupTimingMetric()),
iterations = 5,
startupMode = StartupMode.COLD
) {
pressHome()
startActivityAndWait()
}
}Microbenchmark للتعليمات البرمجية الساخنة
عندما تحتاج إلى معرفة سرعة دالة واحدة، استخدم مكتبة Microbenchmark. فهي تشغّل تعليماتك البرمجية في حلقة ضيقة، وتُجري إحماءً لـ JIT، وتعرض عدد النانوثواني لكل عملية بعد التخلص من الضوضاء.
استخدمها للمحللات، وأدوات التسلسل، والفرز، وأي دالة مساعدة مرتبطة بوحدة المعالجة المركزية تستدعيها بكثرة.
@RunWith(AndroidJUnit4::class)
class JsonParseBenchmark {
@get:Rule val benchmarkRule = BenchmarkRule()
@Test
fun parseLargePayload() {
val raw = loadSampleJson()
benchmarkRule.measureRepeated {
val parsed = parseUsers(raw) // code under test
// assertEquals avoids the compiler dropping the result
assertTrue(parsed.isNotEmpty())
}
}
}تتبّع النظام باستخدام Perfetto
يلتقط تتبّع النظام ما نفذه كل مؤشر ترابط والنظام، إطارًا تلو الآخر. يستطيع محلل وحدة المعالجة المركزية في Android Studio تسجيله، كما يمكنك التقاطه باستخدام adb وفتحه في Perfetto (ui.perfetto.dev).
يعرض التتبّع الإطارات الحمراء المزعجة، والعمل المنفذ على مؤشر الترابط الرئيسي، والوقت المستغرق في وحدة معالجة الرسومات. وهو أفضل أداة منفردة لتشخيص التقطّع.
# Record a 5-second system trace from the command line
adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto-trace \
-t 5s sched freq idle am wm gfx view
# Pull it to your machine, then open in https://ui.perfetto.dev
adb pull /data/misc/perfetto-traces/trace.perfetto-traceأقسام التتبّع المخصصة
تُظهر التتبعات عمل إطار العمل مباشرةً. ولوسم تعليماتك البرمجية الخاصة، لفّها داخل قسم تتبّع ذي اسم. ستظهر هذه الأسماء بعد ذلك على شكل كتل معنونة في Perfetto، ما يجعل اكتشاف نقاط الاختناق أمرًا سهلًا.
استخدم واجهة برمجة التطبيقات androidx.tracing كي تظهر الأقسام في تتبعات التصحيح وتتبعات القياس المعياري معًا.
import androidx.tracing.trace
fun loadDashboard(repo: Repo): Dashboard {
return trace("loadDashboard") {
val user = trace("fetchUser") { repo.user() }
val feed = trace("fetchFeed") { repo.feed() }
Dashboard(user, feed)
}
}
// In Perfetto you will now see named slices:
// loadDashboard > fetchUser, fetchFeedتتبّع الإطارات المسقطة أثناء التشغيل
لا يكون محلل الأداء متصلًا بك دائمًا. إن JankStats مكتبة من Jetpack تُبلغ عن الإطارات المتقطعة من داخل تطبيقك قيد التشغيل، بحيث يمكنك تسجيلها أو إرسال إحصاءات مجمعة إلى أدوات التحليلات.
تتصل المكتبة بالنافذة وتستدعيك كلما تجاوز إطار ما ميزانيته.
val jankStats = JankStats.createAndTrack(window) { frameData ->
if (frameData.isJank) {
Log.w("Jank", "Janky frame: ${frameData.frameDurationUiNanos} ns")
analytics.logJank(frameData.frameDurationUiNanos)
}
}
// Pause/resume with your screen lifecycle
override fun onResume() { super.onResume(); jankStats.isTrackingEnabled = true }
override fun onPause() { super.onPause(); jankStats.isTrackingEnabled = false }قراءة الأرقام: المئينات
يخفي متوسط واحد المشكلات. إذا كان متوسط إطارك 10ms، لكن المئين 99 يبلغ 40ms، فهذا يعني أن 1% من الإطارات متقطعة وسيشعر المستخدمون بذلك. انظر دائمًا إلى P50 وP90 وP99، وليس إلى المتوسط الحسابي فقط.
تعرض المقاييس المعيارية هذه القيم نيابةً عنك. يوضح المساعد أدناه الفكرة باستخدام عينات إطارات خام.
fun percentile(samplesMs: List<Double>, p: Int): Double {
val sorted = samplesMs.sorted()
val index = ((p / 100.0) * (sorted.size - 1)).toInt()
return sorted[index]
}
fun main() {
val frames = listOf(8.0, 9.0, 10.0, 9.5, 11.0, 40.0, 9.0, 10.5)
println("P50 = %.1f ms".format(percentile(frames, 50)))
println("P99 = %.1f ms".format(percentile(frames, 99)))
}سير عمل قابل للتكرار للقياس
تأتي الأرقام الموثوقة من عملية منضبطة. اتبع قائمة التحقق هذه في كل مرة:
- استخدم إصدارًا للإنتاج / غير قابل للتصحيح (مع تفعيل R8).
- شغّل التطبيق على جهاز فعلي موصول بالطاقة، مع حالة حرارية مستقرة.
- كرّر السيناريو عدة مرات وأبلغ عن الوسيط.
- غيّر شيئًا واحدًا في كل مرة وأعد القياس.
- قارن النتائج مع خط أساس محفوظ حتى تتمكن من إثبات التحسن.
إذا تخطيت هذه الخطوات، فسوف تطارد الضوضاء بدلًا من إصلاح المشكلات الحقيقية.
أين يذهب الوقت فعليًا
ينتج معظم التقطّع في Android عن مجموعة صغيرة من الأسباب. ومعرفتها تخبرك إلى أين توجّه أدواتك:
- العمل على مؤشر الترابط الرئيسي: عمليات القرص أو الشبكة أو JSON على مؤشر ترابط واجهة المستخدم.
- إعادة التركيب المفرطة: إعادة Compose رسم أجزاء أكبر بكثير مما ينبغي.
- تكرار التخصيصات: فترات توقف جمع البيانات المهملة.
- مراحل التخطيط: تخطيطات متداخلة بعمق أو يجري قياسها مرارًا.
تتناول الدروس التالية في هذه الدورة إعادة التركيب وتسريبات الذاكرة وبدء التشغيل مباشرةً. والقياس هو ما يخبرك بالمشكلة التي ينبغي إصلاحها أولًا.
تحقق سريع
تريد قياسًا مستقرًا وقابلًا للتكرار للمدة التي يستغرقها بدء التشغيل البارد لتطبيقك على جهاز حقيقي عبر عمليات تشغيل متعددة. ما الأداة الأنسب؟
مراجعة: أصبح بإمكانك القياس الآن
تعلمت أن تجعل الأداء مرئيًا قبل تغيير أي شيء:
- تحدد ميزانية الإطار البالغة 16ms الفرق بين السلاسة والتقطّع.
- تعرض أداة تحليل الأداء في Android Studio بيانات مباشرة عن وحدة المعالجة المركزية والذاكرة والطاقة.
- تمنحك اختبارات Macro وMicrobenchmark أرقامًا قابلة للتكرار.
- تكشف تتبعات Perfetto وأقسام
trace()المخصصة أين يذهب الوقت. - تُبلغ JankStats عن التقطّع من داخل التطبيق قيد التشغيل.
- اقرأ P50/P90/P99، وحلّل إصدارات الإنتاج على أجهزة حقيقية، وغيّر شيئًا واحدًا في كل مرة.
بعد ذلك، سنطبّق هذا على أحد أكبر مصادر التقطّع في Compose: إعادة التركيب.
الأسئلة الشائعة
هل درس «قياس الأداء» مجاني؟
نعم — نص درس «قياس الأداء» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 4 دروس في المجموع.
ماذا ستتعلم في «قياس الأداء»؟
أدوات تحليل الأداء والتتبعات والاختبارات المعيارية تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟
لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «قياس الأداء»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟
نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.