Ghi lại chỉ số Macrobenchmark

Chỉ số là loại thông tin chính được lấy từ các điểm chuẩn của bạn. Các chỉ số này được chuyển đến hàm measureRepeated dưới dạng List, cho phép bạn chỉ định nhiều chỉ số được đo lường cùng một lúc. Bạn phải có ít nhất một loại chỉ số để chạy điểm chuẩn.

Đoạn mã sau đây chỉ ra thời gian kết xuất khung hình và chỉ số của mục dấu vết tuỳ chỉnh cho giao diện bố cục lười biếng 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)
            }
        }
    }

Trong ví dụ sau, EntryRowCustomTrace biểu thị một phần dấu vết tuỳ chỉnh được xác định bên trong các lớp mục có khả năng kết hợp bằng cách sử dụng trình bao bọc khối trace(sectionName) { ... } Kotlin tiêu chuẩn. Để cung cấp dữ liệu cho TraceSectionMetric, bạn phải bao bọc các thành phần giao diện người dùng mục tiêu bên trong toàn bộ mã nguồn phát hành công khai của ứng dụng bằng trình bao bọc khối thời gian chạy Jetpack tiêu chuẩn 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)
            )
        }
    }
}

Kết quả đo điểm chuẩn được xuất trực tiếp sang thẻ Benchmark (Đo điểm chuẩn) trong cửa sổ dòng lệnh của Android Studio, như minh hoạ trong Hình 1. Nếu bạn xác định nhiều chỉ số, thì tất cả các điểm dữ liệu được tính toán của chỉ số đó sẽ được kết hợp trong cửa sổ tóm tắt.

Kết quả của TraceSectionMetric và FrameTimingMetric.
Hình 1. Kết quả kết hợp của TraceSectionMetricFrameTimingMetric trên bảng điều khiển cho một bố cục Compose hiện đại.

StartupTimingMetric, FrameTimingMetric, TraceSectionMetricPowerMetric được đề cập chi tiết bên dưới. Để biết danh sách đầy đủ các chỉ số đo điểm chuẩn có sẵn, hãy xem các lớp con của Metric trong tài liệu tham khảo API.

StartupTimingMetric

StartupTimingMetric thu thập các chỉ số về thời gian khởi động ứng dụng bằng các giá trị sau:

  • timeToInitialDisplayMs: Khoảng thời gian từ khi hệ thống nhận được ý định khởi chạy cho đến khi kết xuất khung hình đầu tiên của màn hình đích.
  • timeToFullDisplayMs: Khoảng thời gian từ khi hệ thống nhận được ý định khởi chạy cho đến khi ứng dụng báo cáo là đã hiển thị đầy đủ bằng cơ chế báo cáo nền tảng nội bộ. Quá trình đo lường sẽ dừng khi hoàn tất quá trình kết xuất khung hình đầu tiên sau (hoặc có chứa) tín hiệu đã hiển thị đầy đủ.

StartupTimingMetric cho ra các giá trị tối thiểu, trung vị và tối đa từ các vòng lặp khởi động. Để đánh giá mức độ cải thiện khi khởi động, hãy luôn tập trung vào các giá trị trung vị, vì các giá trị này cung cấp số liệu ước tính chính xác nhất về thời gian khởi động thông thường của người dùng.

Trong cấu trúc Compose-first, đừng cố gắng gọi activity.reportFullyDrawn theo cách thủ công. Thay vào đó, hãy sử dụng các tiện ích không đồng bộ an toàn cho Compose ReportDrawn, ReportDrawnWhen hoặc ReportDrawnAfter bên trong các thành phần kết hợp màn hình để tự động báo hiệu cho Macrobenchmark khi dữ liệu mạng không đồng bộ hoặc trạng thái giao diện người dùng phức tạp đã kết thúc quá trình kết xuất.

Để biết thêm thông tin về cách phân tích và tối ưu hoá hiệu suất khởi động, hãy xem bài viết Thời gian khởi động ứng dụng.

FrameTimingMetric

FrameTimingMetric ghi lại thông tin thời gian chính xác từ các khung do một hành trình điểm chuẩn tạo ra, chẳng hạn như thao tác cuộn danh sách hoặc ảnh động bố cục giao diện người dùng phức tạp, đồng thời cho ra các giá trị chẩn đoán sau:

  • frameOverrunMs: khoảng thời gian lỡ thời hạn của một khung hình cụ thể. Số dương cho biết khung hình bị rớt kèm theo hiện tượng giật hoặc kết xuất gián đoạn quan sát được. Số âm cho biết một khung hình hoàn thành nhanh hơn thời hạn phần cứng của hệ thống con bao nhiêu. Lưu ý: Chỉ số này chỉ có trên Android 12 (API cấp 31) trở lên.
  • frameDurationCpuMs: khoảng thời gian khung hình được tạo chủ động trên CPU ở cả luồng giao diện người dùng chính của ứng dụng và RenderThread Compose.

Các thông tin đo lường này được thu thập trong phạm vi phân phối: phân vị thứ 50, 90, 95 và 99:

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

Khi tối ưu hoá hệ phân cấp bố cục Jetpack Compose, hãy xem xét những khung hình có hiệu suất kém nhất (các giới hạn P95 và P99). Nếu frameOverrunMs tăng đột biến thành số nguyên dương ở các phân vị cao, thì điều này cho thấy quá trình kết hợp lại đang làm gián đoạn luồng chính trong các ảnh động cuộn nặng.

Để biết thông tin chi tiết hơn về cách xác định và giải quyết các khung hình bị chậm, hãy xem bài viết Hiệu suất của Jetpack Compose.

TraceSectionMetric

TraceSectionMetric ghi lại số lần một phần dấu vết cụ thể xuất hiện và khoảng thời gian tuyệt đối cần thiết để thực thi. Đối với tính năng theo dõi thời gian, công cụ này sẽ xuất ra thời gian tối thiểu, trung vị và tối đa tính bằng mili giây. Phần dấu vết mục tiêu được xác định bằng lệnh gọi hàm trace(sectionName) hoặc ranh giới khối cấp thấp giữa Trace.beginSection(sectionName)Trace.endSection() hay các biến thể không đồng bộ của chúng.

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

Theo mặc định, chỉ số này chỉ xuất ra các phần dấu vết được biên dịch trực tiếp từ các tệp nhị phân gói ứng dụng của riêng bạn. Để đưa các quy trình bắt nguồn từ bên ngoài ranh giới gói của ứng dụng vào, hãy đặt thuộc tính targetPackageOnly = false.

Khi làm việc trên tính năng Theo dõi thời gian chạy Jetpack Compose, bạn có thể hiển thị các hàm có khả năng kết hợp riêng lẻ trong biểu đồ dấu vết hệ thống mà không cần viết trình bao bọc dấu vết theo cách thủ công bằng cách bật tính năng theo dõi thành phần kết hợp.

Mặc dù việc thêm phần phụ thuộc androidx.compose.runtime:runtime-tracing vào ứng dụng mục tiêu là đủ cho các dấu vết của trình phân tích tài nguyên theo cách thủ công, nhưng việc ghi lại các dấu vết này theo phương thức lập trình trong một lần chạy Macrobenchmark đòi hỏi phải có thêm cấu hình bên trong mô-đun đo điểm chuẩn.

Để biết hướng dẫn đầy đủ về cách thiết lập, hãy xem bài viết Ghi lại dấu vết bằng Jetpack Macrobenchmark.

PowerMetric

PowerMetric ghi lại sự thay đổi về điện năng hoặc năng lượng trong suốt quá trình chạy Macrobenchmark. Mỗi danh mục đã chọn được chia nhỏ thành các thành phần phần cứng có thể đo lường, trong khi các danh mục không được chọn sẽ được nhóm vào một nhóm "không được chọn".

Yêu cầu về phần cứng: Các chỉ số này đo lường mức tiêu thụ trên toàn hệ thống thay vì tính toán theo từng ứng dụng. Do đó, việc thu thập dữ liệu chỉ giới hạn ở các thiết bị thực tế của Google Pixel 6, Pixel 6 Pro và các thiết bị thực tế mới hơn.

Chỉ số này đưa ra 2 số đo cho mỗi danh mục:

  • power<category>Uw: mức tiêu thụ điện năng trong khoảng thời gian kiểm thử theo danh mục này (được đo bằng microwatt).
  • energy<category>Uws: tổng lượng năng lượng được truyền trên mỗi đơn vị thời gian trong khoảng thời gian kiểm thử theo danh mục này (được đo bằng microwatt-giây).

Có các danh mục sau:

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

Với một số danh mục (ví dụ như CPU), bạn có thể khó tách riêng công việc do các quy trình khác thực hiện khỏi công việc do ứng dụng của bạn thực hiện. Để giảm thiểu khả năng gây nhiễu này, hãy xoá hoặc hạn chế các ứng dụng và tài khoản không cần thiết.

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

Phân tích các hệ thống con cốt lõi

PowerMetric ghi lại sự thay đổi về điện năng hoặc năng lượng trong khoảng thời gian kiểm thử đối với danh mục công suất được cung cấp. Mỗi danh mục bạn chọn được chia nhỏ thành các thành phần con có thể đo lường, còn các danh mục không được chọn sẽ được thêm vào chỉ số "unselected" (bỏ chọn).

Đầu ra của thiết bị đầu cuối sẽ liên kết với cấu hình mà bạn yêu cầu:

  • powerCategoryCpuUw: Lượng điện năng mà CPU tiêu thụ trong khoảng thời gian kiểm thử.
  • powerCategoryGpuUw: Lượng điện năng mà GPU tiêu thụ trong khoảng thời gian kiểm thử.
  • powerUnselectedUw: Tổng mức tiêu thụ điện năng của tất cả danh mục phần cứng có sẵn không được yêu cầu rõ ràng trong bản đồ khởi tạo.

Để ngăn chặn các đột biến dữ liệu thất thường trên các đường dẫn phần cứng trong quá trình chạy, hãy khoá độ sáng màn hình ở một giá trị cố định, duy trì nhiệt độ ổn định của thiết bị và đóng các quy trình nền cạnh tranh trước khi bắt đầu vòng lặp Macrobenchmark.

Tài nguyên khác

Xem nội dung