Tiến hành đo điểm chuẩn trong tính năng Tích hợp liên tục

Bạn có thể tiến hành đo điểm chuẩn trong tính năng Tích hợp liên tục (CI) để theo dõi hiệu suất theo thời gian và nhận diện lỗi hồi quy hiệu suất (hoặc mức độ cải thiện) trước khi phát hành ứng dụng. Trang này cung cấp thông tin cơ bản về tính năng đo điểm chuẩn trong CI.

Trước khi bắt đầu sử dụng tính năng đo điểm chuẩn trong CI, hãy cân nhắc sự khác biệt giữa việc thu thập và đánh giá kết quả so với hoạt động kiểm thử thông thường.

Kết quả không rõ ràng

Mặc dù đo điểm chuẩn là các phép kiểm thử đo lường, nhưng kết quả không chỉ đơn thuần là đạt/không đạt. Đo điểm chuẩn cung cấp các phép đo thời gian cho thiết bị cụ thể được thực hiện. Biểu diễn đồ thị kết quả theo thời gian cho phép bạn theo dõi sự thay đổi và quan sát độ nhiễu trong hệ thống đo lường.

Sử dụng thiết bị thực

Phép đo điểm chuẩn cần được thực hiện trên thiết bị Android thực. Mặc dù có thể chạy trên trình mô phỏng, nhưng chúng tôi không khuyến khích thực hiện vì phương pháp này không thể hiện trải nghiệm người dùng thực tế và thay vào đó, cung cấp các thông số liên quan đến khả năng của hệ điều và phần cứng của máy chủ. Hãy cân nhắc sử dụng thiết bị thực hoặc dịch vụ cho phép bạn tiến hành kiểm thử trên thiết bị thực, chẳng hạn như Firebase Test Lab (Phòng thử nghiệm Firebase).

Tiến hành đo điểm chuẩn

Việc tiến hành đo điểm chuẩn như một phần trong quy trình CI có thể khác với việc đo điểm chuẩn trên máy cục bộ từ Android Studio. Trên máy, bạn thường chạy các bài kiểm thử tích hợp của Android với một tác vụ connectedCheck Gradle. Tác vụ này tự động tạo APK và kiểm thử APK của bạn, đồng thời tiến hành các bài kiểm thử trên (các) thiết bị hiện được kết nối. Khi chạy trong CI, quy trình này thường cần được tách thành các giai đoạn riêng biệt.

Tạo

Đối với thư viện Microbenchmark, hãy chạy tác vụ Gradle assemble[VariantName]AndroidTest, thao tác này sẽ tạo một APK kiểm thử chứa cả mã ứng dụng và mã đã thử nghiệm của bạn.

Ngoài ra, thư viện Macrobenchmark yêu cầu bạn phải tạo APK mục tiêu và APK kiểm thử riêng biệt. Do đó, hãy chạy các tác vụ Gradle :app:assemble[VariantName]:macrobenchmark:assemble[VariantName].

Cài đặt và chạy

Các bước này thường được thực hiện mà không cần chạy tác vụ Gradle. Lưu ý rằng các bước này có thể được rút gọn tùy thuộc vào việc bạn có sử dụng dịch vụ cho phép thực hiện kiểm thử trên thiết bị thực hay không.

Để cài đặt, hãy sử dụng lệnh adb install và chỉ định APK kiểm thử (hoặc APK mục tiêu).

Chạy lệnh đo lường adb shell am để thực hiện tất cả các phép đo điểm chuẩn.

adb shell am instrument -w com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner

Xin lưu ý rằng khi sử dụng thư viện Macrobenchmark, hãy dùng androidx.test.runner.AndroidJUnitRunner thông thường làm trình chạy đo lường.

Bạn có thể truyền các đối số đo lường tương tự như trong cấu hình Gradle bằng cách sử dụng đối số -e. Để biết tất cả các tùy chọn đối số đo lường, hãy xem các trang dành cho Microbenchmark (Điểm chuẩn vi mô) hoặc Macrobenchmark (Điểm chuẩn vĩ mô).

Ví dụ: bạn có thể đặt đối số dryRunMode để chạy các phép đo điểm chuẩn vi mô trong quy trình xác minh yêu cầu lấy dữ liệu (pull request). Khi kích hoạt cờ hiệu này, phép đo điểm chuẩn vi mô chỉ chạy trong một vòng lặp, cho phép xác minh rằng chúng đang chạy đúng cách mà không mất quá nhiều thời gian để thực thi.

adb shell am instrument -w -e "androidx.benchmark.dryRunMode.enable" "true" com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner

Hãy xem phần Chạy kiểm thử với ADB để biết thêm thông tin về cách chạy kiểm thử đo lường từ dòng lệnh.

Khoá xung nhịp

Trình bổ trợ Gradle Microbenchmark (Điểm chuẩn vi mô) cung cấp lệnh ./gradlew lockClocks để khóa xung nhịp CPU của một thiết bị đã bị can thiệp hệ thống. Thao tác này rất hữu ích nhằm đảm bảo độ ổn định khi bạn có quyền truy cập thiết bị đã bị can thiệp hệ thống, chẳng hạn như bản dựng "userdebug". Bạn có thể thực hiện việc này bằng tập lệnh shell lockClocks.sh có trong nguồn của thư viện.

Bạn có thể chạy tập lệnh trực tiếp từ máy chủ Linux hoặc Mac, hoặc bạn có thể đẩy sang thiết bị bằng một vài lệnh adb:

adb push path/lockClocks.sh /data/local/tmp/lockClocks.sh
adb shell /data/local/tmp/lockClocks.sh
adb shell rm /data/local/tmp/lockClocks.sh

Nếu bạn chạy tập lệnh shell trực tiếp trên máy chủ lưu trữ, các lệnh này sẽ được gửi đến thiết bị được kết nối.

Để biết thêm thông tin về lý do tại sao việc khóa xung nhịp CPU lại hữu ích, hãy xem cách đạt điểm chuẩn nhất quán.

Thu thập kết quả

Các thư viện đo điểm chuẩn sẽ xuất kết quả đo lường dưới dạng JSON, cùng với các tệp theo dõi phân tích vào một thư mục trên thiết bị Android sau mỗi lần chạy phép đo điểm chuẩn. Thư viện Macrobenchmark (Điểm chuẩn vĩ mô) sẽ xuất ra nhiều tệp theo dõi perfetto: mỗi tệp cho một lần lặp được đo lường của mỗi vòng lặp MacrobenchmarkRule.measureRepeated. Tuy nhiên, Microbenchmark (Điểm chuẩn vi mô) chỉ tạo một tệp theo dõi cho tất cả các lần lặp của mỗi BenchmarkRule.measureRepeated. Các tệp theo dõi phân tích cũng được xuất vào thư mục này.

Lưu và định vị tệp

Nếu bạn thực hiện đo điểm chuẩn bằng Gradle, các tệp này sẽ tự động được sao chép sang thiết bị lưu trữ của bạn. Nếu chạy trực tiếp bằng lệnh adb, bạn cần kéo các lệnh đó theo cách thủ công. Theo mặc định, các báo cáo được lưu trên thiết bị trong thư mục media (đa phương tiện) của bộ nhớ ngoài của ứng dụng đã kiểm thử. Để thuận tiện, thư viện sẽ in đường dẫn của tệp vào Logcat. Xin lưu ý rằng thư mục đầu ra có thể khác nhau tùy thuộc vào phiên bản Android của thiết bị đang thực hiện đo điểm chuẩn.

Benchmark: writing results to /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json

Bạn cũng có thể định cấu hình vị trí lưu báo cáo điểm chuẩn trên thiết bị bằng cách sử dụng đối số đo lường additionalTestOutputDir. Thư mục này phải là thư mục có thể ghi bởi ứng dụng của bạn.

adb shell am instrument -w -e additionalTestOutputDir /sdcard/Download/ com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner

Trên Android 10 (API cấp 29) trở lên, các bài kiểm thử ứng dụng sẽ chạy trong một hộp cát theo mặc định để ngăn ứng dụng của bạn truy cập vào các tệp bên ngoài thư mục dành riêng cho ứng dụng. Để có thể lưu vào một số thư mục chung (chẳng hạn như /sdcard/Download), bạn có thể truyền đối số đo lường sau:

-e no-isolated-storage true

Bạn cũng phải cho phép các tùy chọn lưu trữ cũ trong tệp kê khai điểm chuẩn của bạn một cách rõ ràng:

<application android:requestLegacyExternalStorage="true" ... >

Để biết thêm thông tin, hãy xem mục Tạm thời chọn không sử dụng bộ nhớ có giới hạn.

Truy xuất tệp

Để lấy các tệp đã tạo từ thiết bị, bạn có thể sử dụng lệnh adb pull để đưa tệp cụ thể vào thư mục hiện tại trên máy chủ lưu trữ của bạn.

adb pull /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json

Để truy xuất tất cả benchmarkData từ một thư mục cụ thể, hãy xem đoạn mã sau:

# The following command pulls all files ending in -benchmarkData.json from the directory
# hierarchy starting at the root /storage/emulated/0/Android.
adb shell find /sdcard/Download -name "*-benchmarkData.json" | tr -d '\r' | xargs -n1 adb pull

Lưu ý rằng các tệp theo dõi (.trace hoặc .perfetto-trace) được lưu vào cùng một thư mục với benchmarkData.json, do đó bạn có thể thu thập các tệp này theo cách tương tự.

Ví dụ về dữ liệu điểm chuẩn

Thư viện điểm chuẩn tạo tệp JSON chứa thông tin về thiết bị mà nó đang chạy phép đo điểm chuẩn và điểm chuẩn thực tế đã chạy. Đoạn mã sau thể hiện tệp JSON đã tạo.

{
    "context": {
        "build": {
            "brand": "google",
            "device": "blueline",
            "fingerprint": "google/blueline/blueline:12/SP1A.210812.015/7679548:user/release-keys",
            "model": "Pixel 3",
            "version": {
                "sdk": 31
            }
        },
        "cpuCoreCount": 8,
        "cpuLocked": false,
        "cpuMaxFreqHz": 2803200000,
        "memTotalBytes": 3753299968,
        "sustainedPerformanceModeEnabled": false
    },
    "benchmarks": [
        {
            "name": "startup",
            "params": {},
            "className": "com.example.macrobenchmark.startup.SampleStartupBenchmark",
            "totalRunTimeNs": 4975598256,
            "metrics": {
                "timeToInitialDisplayMs": {
                    "minimum": 347.881076,
                    "maximum": 347.881076,
                    "median": 347.881076,
                    "runs": [
                        347.881076
                    ]
                }
            },
            "sampledMetrics": {},
            "warmupIterations": 0,
            "repeatIterations": 3,
            "thermalThrottleSleepSeconds": 0
        }
    ]
}

Tài nguyên khác