ضبط کردن سنجه‌های Macrobenchmark

سنجه‌ها نوع اصلی اطلاعاتی هستند که از محک‌های شما استخراج می‌شوند. این مقادیر به‌عنوان List به تابع measureRepeated ارسال می‌شوند که به شما امکان می‌دهد چندین سنجه اندازه‌گیری‌شده را به‌طور هم‌زمان مشخص کنید. برای اجرای محک، حداقل یک نوع سنجه لازم است.

تکه‌کد زیر زمان‌بندی فریم و سنجه‌های بخش ردیابی سفارشی را برای یک میانای چیدمان تنبل Jetpack Compose ضبط می‌کند:

@OptIn(ExperimentalMetricApi::class)
    @Test
    fun scrollComposeList() {
        benchmarkRule.measureRepeated(
            // [START_EXCLUDE]
            packageName = TARGET_PACKAGE,
            metrics = listOf(
                FrameTimingMetric(),
                // Measure power usage. This is supported on Pixel 6 and later.
                PowerMetric(PowerMetric.Type.Power(
                    mapOf(
                        PowerCategory.CPU to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.DISPLAY to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.GPU to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.NETWORK to PowerCategoryDisplayLevel.TOTAL,
                    )
                )),
                // Measure custom trace sections by name EntryRow (which is added to the EntryRow composable).
                // Mode.Sum measures combined duration and also how many times it occurred in the trace.
                // This way, you can estimate whether a composable recomposes more than it should.
                TraceSectionMetric("EntryRowCustomTrace", TraceSectionMetric.Mode.Sum),
                // This trace section takes into account the SQL wildcard character %,
                // which can find trace sections without the full name.
                // This way, you can measure composables produced by the composition tracing
                // and measure how long they took and how many times they recomposed.
                // WARNING: This metric only shows results when running with composition tracing, otherwise it won't be visible in the outputs.
                TraceSectionMetric("%EntryRow%", TraceSectionMetric.Mode.Sum),
            ),
            // Try switching to different compilation modes to see the effect
            // it has on frame timing metrics.
            compilationMode = CompilationMode.None(),
            startupMode = StartupMode.WARM, // restarts activity each iteration
            iterations = DEFAULT_ITERATIONS,
            // [END_EXCLUDE]
            setupBlock = {
                uiAutomator {
                    // Before starting to measure, navigate to the UI to be measured.
                    startIntent(Intent("$packageName.COMPOSE_ACTIVITY"))
                }
            }
        ) {
            uiAutomator {
                onElement { isScrollable }.fling(Direction.DOWN)
            }
        }
    }

در مثال زیر، EntryRowCustomTrace نشان‌دهنده یک بخش ردیابی سفارشی است که در داخل لایه‌های آیتم قابل ترکیب بااستفاده از بسته‌بندی بلوک استاندارد Kotlin trace(sectionName) { ... } تعریف شده است. برای ارائه داده برای TraceSectionMetric، باید مؤلفه‌های میانای کاربر هدف را در داخل پایگاه کد تولید برنامه خود با بسته‌بندی بلوک زمان اجرای استاندارد Jetpack trace بپیچید:

@Composable
private fun EntryRow(entry: Entry, modifier: Modifier = Modifier) = trace("EntryRowCustomTrace") {
    Card(modifier = modifier) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text(
                text = entry.contents,
                modifier = Modifier
                    .padding(16.dp)
                    .wrapContentSize()
            )

            Spacer(modifier = Modifier.weight(1f))

            Checkbox(
                checked = false,
                onCheckedChange = {},
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}

نتایج محک‌زنی مستقیماً در برگه پایانه محک‌زنی در «استودیو Android» برونداد می‌شود، همان‌طور که در شکل ۱ نشان داده شده است. اگر چند سنجه تعریف شده باشد، همه نقطه‌های داده محاسبه‌شده آن‌ها در پنجره خلاصه ترکیب می‌شود.

نتایج TraceSectionMetric و FrameTimingMetric.
شکل ۱. نتایج کنسول ترکیبی TraceSectionMetric و FrameTimingMetric برای چیدمان Compose مدرن.

‫StartupTimingMetric،‏ FrameTimingMetric،‏ TraceSectionMetric، و PowerMetric در زیر به‌طور مفصل پوشش داده شده‌اند. برای فهرست کامل سنجه‌های محک‌زنی دردسترس، زیرکلاس‌های Metric را در مرجع میانای برنامه‌سازی کاربردی ببینید.

StartupTimingMetric

StartupTimingMetric سنجه‌های زمان‌بندی راه‌اندازی برنامه را با مقادیر زیر ضبط می‌کند:

  • ‫timeToInitialDisplayMs: مدت‌زمان سپری‌شده از وقتی که سیستم هدف راه‌اندازی را دریافت می‌کند تا وقتی که اولین قاب صفحه مقصد را ارائه می‌کند.
  • timeToFullDisplayMs: مدت زمانی که طول می‌کشد تا سیستم هدف راه‌اندازی را دریافت کند و برنامه بااستفاده از سازوکارهای گزارش‌دهی پلاتفرم داخلی، گزارش کاملاً ترسیم‌شده را ارائه دهد. اندازه‌گیری با تکمیل شدن پرداخت اولین فریم پس‌از سیگنال کاملاً ترسیم‌شده یا حاوی آن متوقف می‌شود.

StartupTimingMetric مقادیر حداقل، میانه، و حداکثر را از تکرارهای راه‌اندازی برونداد می‌کند. برای ارزیابی بهبود راه‌اندازی، همیشه روی مقادیر میانه تمرکز کنید، زیرا بهترین تخمین را از زمان‌های راه‌اندازی معمول کاربر ارائه می‌دهند.

در معماری Compose-first، سعی نکنید activity.reportFullyDrawn را به‌صورت دستی فراخوانی کنید. درعوض، از ابزارهای کمکی ناهمگام Compose-safe ReportDrawn، ReportDrawnWhen، یا ReportDrawnAfter در composable صفحه‌نمایش خود استفاده کنید تا وقتی پرداز داده‌های شبکه ناهمگام یا حالت‌های پیچیده واسط کاربر به‌پایان رسید، به‌طور خودکار به Macrobenchmark علامت دهد.

برای اطلاعات بیشتر درباره تجزیه‌وتحلیل و بهینه‌سازی عملکرد مقداردهی اولیه، به زمان راه‌اندازی برنامه مراجعه کنید.

FrameTimingMetric

FrameTimingMetric اطلاعات زمان‌بندی دقیق را از قاب‌های تولیدشده توسط سفر محک، مانند پیمایش فهرست یا پویانمایی پیچیده چیدمان میانای کاربر، ضبط می‌کند و مقادیر تشخیصی زیر را برونداد می‌کند:

  • ‫frameOverrunMs: مدت زمانی که یک قاب معین از سررسید خود عقب می‌ماند. اعداد مثبت نشان‌دهنده فریم حذف‌شده همراه با لرزش یا لکنت قابل‌مشاهده است. اعداد منفی نشان می‌دهند که یک فریم چقدر سریع‌تر نسبت به مهلت سخت‌افزار زیرسیستم تکمیل شده است. توجه: این سنجه فقط در Android 12 (سطح میانای برنامه‌سازی کاربردی ۳۱) و نسخه‌های جدیدتر دردسترس است.
  • frameDurationCpuMs: مدت زمانی که قاب به‌طور فعال در CPU در رشته میانای کاربر برنامه اصلی و Compose RenderThread تولید می‌شود.

این اندازه‌گیری‌ها در توزیع صدک‌های ۵۰، ۹۰، ۹۵، و ۹۹ جمع‌آوری می‌شوند:

frameDurationCpuMs P50 3.5, P90 6.0, P95 6.4, P99 11.0
frameOverrunMs P50 -11.6, P90 -7.2, P95 -7.1, P99 -1.2

هنگام بهینه‌سازی سلسله‌مراتب طرح‌بندی Jetpack Compose، به فریم‌های با بدترین عملکرد (حدود P95 و P99) نگاه کنید. اگر frameOverrunMs در صدک‌های بالا به اعداد صحیح مثبت جهش کند، نشان می‌دهد که بازترکیب‌ها درطول پویانمایی‌های پیمایش سنگین، رشته اصلی را متوقف می‌کنند.

برای اطلاعات آماری عمیق‌تر درباره شناسایی و حل فریم‌های کند، به عملکرد Jetpack Compose مراجعه کنید.

TraceSectionMetric

TraceSectionMetric تعداد دفعاتی را که بخش ردیابی خاصی رخ می‌دهد و مقدار مطلق زمانی را که برای اجرا نیاز دارد ضبط می‌کند. برای ردگیری زمان، حداقل، میانه، و حداکثر زمان را برحسب میلی‌ثانیه خروجی می‌دهد. بخش ردیابی هدف یا با فراخوانی تابع trace(sectionName) یا با مرزهای بلوک سطح پایین‌تر بین Trace.beginSection(sectionName) و Trace.endSection() یا انواع ناهمگام آن‌ها تعریف می‌شود.

EntryRowCustomTraceCount min 20.0, median 28.0, max 50.0
EntryRowCustomTraceSumMs min 34.9, median 44.4, max 66.6

به‌طور پیش‌فرض، این سنجه فقط بخش‌های ردیابی را که مستقیماً از باینری‌های بسته برنامه خودتان کامپایل شده‌اند برونداد می‌کند. برای گنجاندن فرایندهایی که از خارج از مرز بسته برنامه‌تان منشأ می‌گیرند، ویژگی targetPackageOnly = false را تنظیم کنید.

هنگام کار روی Jetpack Compose Runtime Tracing، می‌توانید با فعال کردن ردگیری ترکیب‌بندی، توابع ترکیب‌پذیر مجزا را در نمودارهای ردگیری سیستم خود بدون نوشتن پوشاننده‌های ردگیری دستی نمایش دهید.

درحالی‌که افزودن وابستگی androidx.compose.runtime:runtime-tracing به برنامه هدف شما برای ردیابی‌های نمایه‌ساز دستی کافی است، ضبط این ردیابی‌ها به‌صورت برنامه‌نویسی‌شده در اجرای Macrobenchmark به پیکربندی اضافی در داخل واحد محک شما نیاز دارد.

برای دستورالعمل‌های کامل راه‌اندازی، به ردگیری با Jetpack Macrobenchmark مراجعه کنید.

PowerMetric

PowerMetric تغییرات توان یا انرژی را درطول مدت اجرای Macrobenchmark شما ثبت می‌کند. هر دسته انتخاب‌شده به اجزای سخت‌افزاری قابل‌اندازه‌گیری خود تقسیم می‌شود، درحالی‌که دسته‌های انتخاب‌نشده در یک گروه «انتخاب‌نشده» قرار می‌گیرند.

الزامات سخت‌افزاری: این سنجه‌ها مصرف کل سیستم را اندازه‌گیری می‌کنند نه محاسبات مربوط به هر برنامه را. درنتیجه، جمع‌آوری داده‌ها به دستگاه‌های فیزیکی Google Pixel 6،‏ Pixel 6 Pro، و دستگاه‌های فیزیکی جدیدتر محدود می‌شود.

این سنجه دو اندازه‌گیری برای هر دسته ارائه می‌دهد:

  • power<category>Uw: مقدار توان مصرف‌شده درطول مدت آزمایش شما در این دسته (برحسب میکرووات اندازه‌گیری می‌شود).
  • energy<category>Uws: مقدار کل انرژی منتقل‌شده در واحد زمان درطول مدت آزمایش شما در این دسته (برحسب میکرووات-ثانیه اندازه‌گیری می‌شود).

دسته‌ها شامل موارد زیر است:

  • CPU
  • DISPLAY
  • GPU
  • GPS
  • MEMORY
  • MACHINE_LEARNING
  • NETWORK
  • UNCATEGORIZED

در برخی‌از دسته‌ها، مثل CPU، ممکن است جدا کردن کار انجام‌شده توسط فرایندهای دیگر از کار انجام‌شده توسط برنامه شما دشوار باشد. برای به‌حداقل رساندن تداخل، برنامه‌ها و حساب‌های غیرضروری را بردارید یا محدود کنید.

powerCategoryCpuUw min 300.2, median 346.1, max 519.6
powerCategoryDisplayUw min 319.8, median 325.8, max 329.7
powerCategoryGpuUw min 18.8, median 23.3, max 36.9
powerCategoryNetworkUw min 97.3, median 123.3, max 681.3
powerTotalUw min 1234.8, median 1316.6, max 2112.4
powerUnselectedUw       min  483.3,  median  512.6,  max  561.7

درحال تجزیه‌وتحلیل زیرسیستم‌های اصلی

PowerMetric تغییرات در توان یا انرژی را درطول مدت آزمایش شما برای دسته‌های توان ارائه‌شده ثبت می‌کند. هر دسته‌ای که انتخاب می‌کنید به زیرمؤلفه‌های قابل‌اندازه‌گیری‌اش تقسیم می‌شود و دسته‌های انتخاب‌نشده به سنجه «انتخاب‌نشده» اضافه می‌شوند.

خروجی‌های پایانه با پیکربندی درخواستی شما مطابقت دارد:

  • powerCategoryCpuUw: مقدار برقی که واحد پردازش مرکزی درطول مدت آزمایش شما مصرف کرده است.
  • powerCategoryGpuUw: مقدار برق مصرف‌شده توسط واحد پردازش گرافیکی درطول مدت آزمایش شما.
  • powerUnselectedUw: مجموع توان مصرف‌شده توسط همه دسته‌های سخت‌افزاری دردسترس که به‌طور صریح در نقشه مقداردهی اولیه شما درخواست نشده‌اند.

برای جلوگیری از جهش‌های نامنظم داده‌ها در ریل‌های سخت‌افزاری درطول اجرا، روشنایی صفحه قفل را روی مقدار ثابتی قفل کنید، دمای دستگاه را پایدار نگه دارید، و فرایندهای پس‌زمینه‌ای رقیب را قبل‌از شروع حلقه Macrobenchmark ببندید.

منابع بیشتر

محتوا را مشاهده می‌کند