برای یادگیری نحوه استفاده از کتابخانه Microbenchmark با افزودن تغییرات به کد برنامه خود، به بخش Quickstart مراجعه کنید. برای یادگیری نحوه تکمیل یک راهاندازی کامل با تغییرات پیچیدهتر در پایگاه کد خود، بخش راهاندازی کامل پروژه را ببینید.
شروع سریع
این بخش نشان می دهد که چگونه می توان بنچمارک را امتحان کرد و اندازه گیری های یکباره را بدون نیاز به انتقال کد به ماژول ها انجام داد. برای نتایج دقیق عملکرد، این مراحل شامل غیرفعال کردن اشکالزدایی در برنامه شما میشود، بنابراین بدون انجام تغییرات در سیستم کنترل منبع، آن را در یک نسخه محلی محلی نگه دارید.
برای انجام محک زدن یکباره، موارد زیر را انجام دهید:
کتابخانه را به فایل
build.gradle
یاbuild.gradle.kts
ماژول خود اضافه کنید:کاتلین
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
شیار
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
از وابستگی
implementation
به جای وابستگیandroidTestImplementation
استفاده کنید. اگر ازandroidTestImplementation
استفاده می کنید، معیارها اجرا نمی شوند زیرا مانیفست کتابخانه در مانیفست برنامه ادغام نشده است.نوع ساخت
debug
را بهروزرسانی کنید تا قابل اشکالزدایی نباشد:کاتلین
android { ... buildTypes { debug { isDebuggable = false } } }
شیار
android { ... buildTypes { debug { debuggable false } } }
testInstrumentationRunner
را بهAndroidBenchmarkRunner
تغییر دهید:کاتلین
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
شیار
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
یک نمونه از
BenchmarkRule
در یک فایل آزمایشی در فهرست راهنمایandroidTest
اضافه کنید تا معیار خود را اضافه کنید. برای اطلاعات بیشتر در مورد نوشتن معیارها، به ایجاد کلاس Microbenchmark مراجعه کنید.قطعه کد زیر نحوه اضافه کردن یک معیار به یک تست ابزاری را نشان می دهد:
کاتلین
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
جاوا
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { BenchmarkRuleKt.measureRepeated( (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork() ); } } }
برای یادگیری نحوه نوشتن معیار، به کلاس Create a Microbenchmark بروید.
راه اندازی کامل پروژه
برای تنظیم معیارهای معمولی به جای محک زدن یکباره، معیارها را در ماژول خود جدا کنید. این کمک می کند تا اطمینان حاصل شود که پیکربندی آنها، مانند تنظیم debuggable
روی false
، از آزمایش های معمولی جدا است.
از آنجایی که Microbenchmark کد شما را مستقیماً اجرا می کند، کدی را که می خواهید محک بزنید در یک ماژول Gradle جداگانه قرار دهید و مطابق شکل 1 به آن ماژول وابستگی تنظیم کنید.
برای افزودن یک ماژول جدید Gradle، میتوانید از ماژول ویزارد در Android Studio استفاده کنید. ویزارد ماژولی را ایجاد می کند که برای محک گذاری از قبل پیکربندی شده است، با یک فهرست محک اضافه شده و debuggable
روی false
تنظیم شده است.
روی پروژه یا ماژول خود در پنل Project در Android Studio کلیک راست کنید و روی New > Module کلیک کنید.
Benchmark را در قسمت Templates انتخاب کنید.
Microbenchmark را به عنوان نوع ماژول معیار انتخاب کنید.
برای نام ماژول "microbenchmark" را تایپ کنید.
روی Finish کلیک کنید.
پس از ایجاد ماژول، فایل build.gradle
یا build.gradle.kts
آن را تغییر دهید و androidTestImplementation
به ماژول حاوی کد برای بنچمارک اضافه کنید:
کاتلین
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
شیار
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
یک کلاس Microbenchmark ایجاد کنید
معیارها تست های استاندارد ابزار دقیق هستند. برای ایجاد یک معیار، از کلاس BenchmarkRule
ارائه شده توسط کتابخانه استفاده کنید. برای محک زدن فعالیتها، از ActivityScenario
یا ActivityScenarioRule
استفاده کنید. برای محک زدن کد UI، از @UiThreadTest
استفاده کنید.
کد زیر یک بنچمارک نمونه را نشان می دهد:
کاتلین
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
جاوا
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { final BenchmarkState state = benchmarkRule.getState(); while (state.keepRunning()) { doSomeWork(); } } }
زمانبندی را برای راهاندازی غیرفعال کنید
میتوانید زمانبندی بخشهایی از کد را که نمیخواهید اندازهگیری کنید، با بلوک runWithTimingDisabled{}
غیرفعال کنید. این بخشها معمولاً کدهایی را نشان میدهند که باید در هر تکرار از معیار اجرا کنید.
کاتلین
// 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) }
جاوا
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)); }
سعی کنید میزان کار انجام شده در داخل بلوک measureRepeated
و داخل runWithTimingDisabled
را به حداقل برسانید. بلوک measureRepeated
چندین بار اجرا می شود و می تواند بر زمان کلی مورد نیاز برای اجرای معیار تأثیر بگذارد. اگر نیاز به تأیید برخی از نتایج یک معیار دارید، میتوانید به جای انجام هر بار تکرار معیار، آخرین نتیجه را اعلام کنید.
معیار را اجرا کنید
در Android Studio، همانطور که در شکل 3 نشان داده شده است، معیار خود را مانند هر @Test
با استفاده از عمل ناودان در کنار کلاس یا روش تست خود اجرا کنید.
از طرف دیگر، از خط فرمان، connectedCheck
را اجرا کنید تا همه آزمایشها از ماژول Gradle مشخص شده اجرا شوند:
./gradlew benchmark:connectedCheck
یا یک تست واحد:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
نتایج محک
پس از اجرای موفقیتآمیز Microbenchmark، معیارها مستقیماً در Android Studio نمایش داده میشوند و یک گزارش معیار کامل با معیارهای اضافی و اطلاعات دستگاه در قالب JSON در دسترس است.
گزارشهای JSON و هرگونه ردیابی پروفایل نیز بهطور خودکار از دستگاهی به میزبان دیگر کپی میشوند. اینها روی ماشین میزبان در مکان زیر نوشته شده است:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
بهطور پیشفرض، گزارش JSON روی دیسک روی دستگاه در پوشه رسانه مشترک خارجی APK آزمایشی نوشته میشود، که معمولاً در /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
قرار دارد. /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
خطاهای پیکربندی
کتابخانه شرایط زیر را شناسایی می کند تا مطمئن شود که پروژه و محیط شما برای عملکرد دقیق انتشار تنظیم شده است:
- Debuggable روی
false
تنظیم شده است. - یک دستگاه فیزیکی در حال استفاده است - شبیه سازها پشتیبانی نمی شوند.
- اگر دستگاه روت شده باشد ساعت ها قفل می شوند.
- سطح باتری کافی در دستگاه حداقل 25٪.
اگر هر یک از بررسی های قبلی با شکست مواجه شود، معیار یک خطا را گزارش می کند تا از اندازه گیری های نادرست جلوگیری کند.
برای سرکوب انواع خطاهای خاص به عنوان اخطار و جلوگیری از توقف معیار، نوع خطا را در فهرستی جدا شده با کاما به آرگومان ابزار دقیق androidx.benchmark.suppressErrors
منتقل کنید.
می توانید این را از اسکریپت Gradle خود تنظیم کنید، همانطور که در مثال زیر نشان داده شده است:
کاتلین
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
شیار
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
همچنین می توانید خطاها را از خط فرمان سرکوب کنید:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
سرکوب کردن خطاها به معیار اجازه میدهد در حالت پیکربندی نادرست اجرا شود و خروجی معیار عمداً با اضافه کردن نامهای آزمایشی با خطا تغییر نام میدهد. برای مثال، اجرای یک معیار قابل اشکالزدایی با سرکوب در قطعه قبلی، نامهای آزمایشی را با DEBUGGABLE_
اضافه میکند.
برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- یک ماکرو بنچمارک بنویسید
- ساخت Microbenchmark بدون Gradle
- ایجاد نمایه های پایه {:#creating-profile-rules}