פרופילים בסיסיים של ההשוואה לשוק עם ספריית Macrobenchmark

מומלץ להשתמש ב-Jetpack Macrobenchmark כדי לבדוק את ביצועי האפליקציה כשפרופילי Baseline מופעלים, ואז להשוות את התוצאות האלה לנקודת השוואה שבה פרופילי Baseline מושבתים. בגישה הזו, אתם יכולים למדוד את זמן ההפעלה של האפליקציה – גם את הזמן עד לתצוגה הראשונית וגם את הזמן עד לתצוגה המלאה – או את ביצועי העיבוד בזמן הריצה, כדי לבדוק אם הפריימים שנוצרו עלולים לגרום לקיטועים.

בדיקות Macrobenchmark מאפשרות לכם לשלוט בהידור שלפני המדידה באמצעות ה-API‏ CompilationMode. אפשר להשתמש בערכים שונים של CompilationMode כדי להשוות בין הביצועים במצבי קימפול שונים. בקטע הקוד הבא אפשר לראות איך משתמשים בפרמטר CompilationMode כדי למדוד את היתרון של פרופילי Baseline:

@RunWith(AndroidJUnit4ClassRunner::class)
class ColdStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    // No ahead-of-time (AOT) compilation at all. Represents performance of a
    // fresh install on a user's device if you don't enable Baseline Profiles—
    // generally the worst case performance.
    @Test
    fun startupNoCompilation() = startup(CompilationMode.None())

    // Partial pre-compilation with Baseline Profiles. Represents performance of
    // a fresh install on a user's device.
    @Test
    fun startupPartialWithBaselineProfiles() =
        startup(CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require))

    // Partial pre-compilation with some just-in-time (JIT) compilation.
    // Represents performance after some app usage.
    @Test
    fun startupPartialCompilation() = startup(
        CompilationMode.Partial(
            baselineProfileMode = BaselineProfileMode.Disable,
            warmupIteration = 3
        )
    )

    // Full pre-compilation. Generally not representative of real user
    // experience, but can yield more stable performance metrics by removing
    // noise from JIT compilation within benchmark runs.
    @Test
    fun startupFullCompilation() = startup(CompilationMode.Full())

    private fun startup(compilationMode: CompilationMode) = benchmarkRule.measureRepeated(
        packageName = "com.example.macrobenchmark.target",
        metrics = listOf(StartupTimingMetric()),
        compilationMode = compilationMode,
        iterations = 10,
        startupMode = StartupMode.COLD,
        setupBlock = {
            pressHome()
        }
    ) {
        uiAutomator {
            startApp(packageName)
            onElement(5_000) { viewIdResourceName == "my-content"}
        }
    }
}

בצילום המסך הבא אפשר לראות את התוצאות ישירות ב-Android Studio, אחרי שהרצנו את האפליקציה לדוגמה Now in Android ב-Google Pixel 7. התוצאות מראות שהפעלת האפליקציה היא המהירה ביותר כשמשתמשים בפרופילים של Baseline‏ (229.0ms) בהשוואה למצב ללא קימפול (324.8ms).

תוצאות של ColdstartupBenchmark
תרשים 1. תוצאות של ColdStartupBenchmark שמציגות את הזמן עד לתצוגה הראשונית ללא הידור (324 אלפיות השנייה), הידור מלא (315 אלפיות השנייה), הידור חלקי (312 אלפיות השנייה) ופרופילי Baseline (229 אלפיות השנייה).

בדוגמה הקודמת מוצגות תוצאות של הפעלת אפליקציה שתועדו באמצעות StartupTimingMetric, אבל יש מדדים חשובים אחרים שכדאי להביא בחשבון, כמו FrameTimingMetric. מידע נוסף על כל סוגי המדדים זמין במאמר תיעוד מדדי Macrobenchmark.

זמן עד לתצוגה מלאה

הדוגמה הקודמת מודדת את הזמן להצגה ראשונית (TTID), שהוא הזמן שלוקח לאפליקציה ליצור את הפריים הראשון שלה. עם זאת, זה לא בהכרח משקף את הזמן עד שהמשתמש יכול להתחיל להשתמש באפליקציה. המדד זמן עד לתצוגה מלאה (TTFD) שימושי יותר למדידה ולאופטימיזציה של נתיבי הקוד שנדרשים כדי שהאפליקציה תהיה במצב שמיש לחלוטין.

אנחנו ממליצים לבצע אופטימיזציה גם ל-TTID וגם ל-TTFD, כי שניהם חשובים. זמן TTID קצר עוזר למשתמש לראות שהאפליקציה באמת מופעלת. חשוב שזמן ה-TTFD יהיה קצר כדי שהמשתמש יוכל לבצע פעולות באפליקציה במהירות.

במאמר שיפור הדיוק של תזמון ההפעלה מפורטות אסטרטגיות לדיווח כשהממשק של האפליקציה משורטט במלואו.