Để tìm hiểu cách sử dụng thư viện Microbenchmark bằng cách thêm các thay đổi vào mã xử lý ứng dụng của bạn, hãy xem phần Bắt đầu nhanh. Để tìm hiểu cách hoàn tất quá trình thiết lập đầy đủ với các thay đổi phức tạp hơn cho cơ sở mã của bạn, hãy xem phần Thiết lập dự án đầy đủ.
Bắt đầu nhanh
Phần này trình bày cách dùng thử tính năng đo điểm chuẩn và chạy các phép đo một lần mà không cần di chuyển mã vào các mô-đun. Để thu được kết quả hiệu suất chính xác, các bước sau đây liên quan đến việc tắt tính năng gỡ lỗi trong ứng dụng của bạn. Vì vậy, hãy thực hiện việc này trong bản sao làm việc cục bộ mà không sửa đổi hệ thống kiểm soát nguồn của mình.
Để thực hiện phép đo điểm chuẩn một lần, hãy làm như sau:
Thêm thư viện vào tệp
build.gradle
hoặcbuild.gradle.kts
trong mô-đun của bạn:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Sử dụng phần phụ thuộc
implementation
thay vì phần phụ thuộcandroidTestImplementation
. Nếu bạn sử dụngandroidTestImplementation
, các điểm chuẩn sẽ không chạy được vì tệp kê khai của thư viện không được hợp nhất vào tệp kê khai của ứng dụng.Cập nhật loại bản dựng
debug
để không thể gỡ lỗi:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Thay đổi
testInstrumentationRunner
thànhAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Thêm một thực thể
BenchmarkRule
vào tệp kiểm thử trong thư mụcandroidTest
để thêm điểm chuẩn. Để biết thêm thông tin về cách viết điểm chuẩn, hãy xem phần Tạo lớp Microbenchmark.Đoạn mã sau đây cho biết cách thêm điểm chuẩn vào một hoạt động kiểm thử đo lường:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { BenchmarkRuleKt.measureRepeated( (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork() ); } } }
Để tìm hiểu cách viết điểm chuẩn, hãy chuyển đến phần Tạo lớp Microbenchmark.
Thiết lập dự án đầy đủ
Để thiết lập việc đo điểm chuẩn thông thường thay vì đo điểm chuẩn một lần, hãy tách các điểm chuẩn thành từng mô-đun riêng. Điều này giúp đảm bảo rằng cấu hình của các điểm chuẩn, chẳng hạn như đặt debuggable
thành false
, được tách biệt với các bài kiểm thử thông thường.
Vì Microbenchmark chạy mã trực tiếp, nên hãy đặt mã bạn muốn đo điểm chuẩn vào một mô-đun Gradle riêng biệt và thiết lập phần phụ thuộc trên mô-đun đó như minh hoạ trong hình 1.
Để thêm mô-đun Gradle mới, bạn có thể dùng trình hướng dẫn mô-đun trong Android Studio. Trình hướng dẫn sẽ tạo một mô-đun được định cấu hình sẵn để đo điểm chuẩn, trong đó có một thư mục điểm chuẩn được thêm và debuggable
được đặt thành false
.
Nhấp chuột phải vào dự án hoặc mô-đun của bạn trong bảng điều khiển Project (Dự án) trong Android Studio rồi nhấp vào New > Module (Mới > Mô-đun).
Chọn Benchmark (Điểm chuẩn) trong ngăn Templates (Mẫu).
Chọn loại mô-đun điểm chuẩn là Microbenchmark.
Nhập "microbenchmark" làm tên mô-đun.
Nhấp vào Finish (Hoàn tất).
Sau khi tạo mô-đun, hãy thay đổi tệp build.gradle
hoặc build.gradle.kts
rồi thêm androidTestImplementation
vào mô-đun chứa mã để đo điểm chuẩn:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Tạo lớp Microbenchmark
Điểm chuẩn là các bài kiểm thử đo lường tiêu chuẩn. Để tạo điểm chuẩn, hãy sử dụng lớp
BenchmarkRule
do thư viện cung cấp. Để đo điểm chuẩn các hoạt động, hãy dùng
ActivityScenario
hoặc ActivityScenarioRule
. Để đo điểm chuẩn mã giao diện người dùng,
hãy dùng @UiThreadTest
.
Mã dưới đây là một điểm chuẩn mẫu:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { final BenchmarkState state = benchmarkRule.getState(); while (state.keepRunning()) { doSomeWork(); } } }
Tắt thời gian thiết lập
Bạn có thể tắt thời gian cho các phần mã mà mình không muốn đo lường bằng block (khối) runWithTimingDisabled{}
. Những phần này thường đại diện cho một số mã mà bạn cần chạy trong mỗi lần lặp lại của điểm chuẩn.
Kotlin
// using random with the same seed, so that it generates the same data every run private val random = Random(0) // create the array once and just copy it in benchmarks private val unsorted = IntArray(10_000) { random.nextInt() } @Test fun benchmark_quickSort() { // ... benchmarkRule.measureRepeated { // copy the array with timing disabled to measure only the algorithm itself listToSort = runWithTimingDisabled { unsorted.copyOf() } // sort the array in place and measure how long it takes SortingAlgorithms.quickSort(listToSort) } // assert only once not to add overhead to the benchmarks assertTrue(listToSort.isSorted) }
Java
private final int[] unsorted = new int[10000]; public SampleBenchmark() { // Use random with the same seed, so that it generates the same data every // run. Random random = new Random(0); // Create the array once and copy it in benchmarks. Arrays.setAll(unsorted, (index) -> random.nextInt()); } @Test public void benchmark_quickSort() { final BenchmarkState state = benchmarkRule.getState(); int[] listToSort = new int[0]; while (state.keepRunning()) { // Copy the array with timing disabled to measure only the algorithm // itself. state.pauseTiming(); listToSort = Arrays.copyOf(unsorted, 10000); state.resumeTiming(); // Sort the array in place and measure how long it takes. SortingAlgorithms.quickSort(listToSort); } // Assert only once, not to add overhead to the benchmarks. assertTrue(SortingAlgorithmsKt.isSorted(listToSort)); }
Hãy cố gắng giảm thiểu lượng công việc thực hiện bên trong khối measureRepeated
, cũng như trong runWithTimingDisabled
. Khối measureRepeated
được chạy nhiều lần và có thể ảnh hưởng đến tổng thời gian cần thiết để chạy điểm chuẩn. Nếu cần xác minh một số kết quả điểm chuẩn, thì bạn có thể xác nhận kết quả cuối cùng thay vì thực hiện trong mỗi lần lặp lại của điểm chuẩn.
Tiến hành đo điểm chuẩn
Trong Android Studio, hãy chạy điểm chuẩn như bất kỳ @Test
nào sử dụng thao tác định hướng bên cạnh lớp hoặc phương thức kiểm thử của bạn, như minh hoạ trong hình 3.
Ngoài ra, từ dòng lệnh, hãy chạy connectedCheck
để thực hiện tất cả các phép kiểm thử từ mô-đun Gradle được chỉ định:
./gradlew benchmark:connectedCheck
Hoặc một phép kiểm thử đơn:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Kết quả đo điểm chuẩn
Sau khi chạy Microbenchmark thành công, các chỉ số sẽ hiển thị ngay trong Android Studio và báo cáo đầy đủ về điểm chuẩn có thông tin bổ sung về thiết bị và chỉ số sẽ có sẵn ở định dạng JSON.
Các báo cáo JSON và mọi dấu vết lập hồ sơ cũng được tự động sao chép từ thiết bị sang máy chủ lưu trữ. Những nội dung này được ghi trên máy chủ lưu trữ tại vị trí sau:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Theo mặc định, báo cáo JSON được ghi vào ổ đĩa trên thiết bị trong thư mục phương tiện được chia sẻ bên ngoài của APK kiểm thử, thường đặt trong /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Lỗi cấu hình
Thư viện sẽ phát hiện các điều kiện sau nhằm đảm bảo dự án của bạn và môi trường được thiết lập để đạt hiệu suất chính xác:
- Debuggable (có thể gỡ lỗi) được đặt thành
false
. - Có thiết bị thực đang được sử dụng (không hỗ trợ trình mô phỏng).
- Xung nhịp đã được khoá nếu thiết bị đã bị can thiệp vào hệ thống.
- Thiết bị có đủ mức pin cần thiết, ít nhất là 25%.
Nếu có lượt kiểm tra nào trước đó không thành công, thì điểm chuẩn sẽ báo lỗi để không khuyến khích đo lường không chính xác.
Để loại bỏ các loại lỗi cụ thể dưới dạng cảnh báo và ngăn các lỗi này tạm dừng hoạt động đo điểm chuẩn, hãy chuyển loại lỗi trong danh sách được phân tách bằng dấu phẩy cho đối số đo lường androidx.benchmark.suppressErrors
.
Bạn có thể thiết lập tuỳ chọn này từ tập lệnh Gradle như trong ví dụ sau:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Bạn cũng có thể loại bỏ các lỗi bằng dòng lệnh:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
Việc loại bỏ lỗi cho phép điểm chuẩn chạy ở trạng thái được định cấu hình không chính xác và kết quả đầu ra của điểm chuẩn được đổi tên có chủ đích bằng cách đưa tên lỗi vào trước tên phép kiểm thử. Ví dụ: việc tiến hành đo điểm chuẩn có thể gỡ lỗi với tuỳ chọn loại bỏ lỗi trong đoạn mã trước đó sẽ thêm DEBUGGABLE_
vào trước tên phép kiểm thử.
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiển thị khi JavaScript tắt
- Viết một Macrobenchmark
- Xây dựng Microbenchmark mà không cần Gradle
- Tạo Hồ sơ cơ sở {:#creating-profile-rules}