benchmark.gradle (5033B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 // This comment contains the central documentation for how we configured Jetpack Benchmark. Currently: 6 // - microbenchmark: configured differently than recommended (see inline notes below) 7 // - macrobenchmark: not configured 8 // 9 // To run our benchmarks, you need to set the "benchmark" gradle property. You can: 10 // - (preferred) Run via the command line (change the class you run on): 11 // ./gradlew -Pbenchmark app:connectedCheck -Pandroid.testInstrumentationRunnerArguments.class=org.mozilla.fenix.perf.SampleBenchmark 12 // - Use the IDE. Temporarily set the "benchmark" property in app/build.gradle with "ext.benchmark=true" 13 // near the top of the file. DO NOT COMMIT THIS. 14 // - (note: I was unable to get IDE run configurations working) 15 // 16 // To get the results, look at this file (we recommend using the median; results are in nanoseconds): 17 // app/build/outputs/connected_android_test_additional_output/nightlyAndroidTest/connected/<device>/org.mozilla.fenix-benchmarkData.json 18 // 19 // I was unable to get the results to print directly in Android Studio (perhaps it's my device). 20 // 21 // The official documentation suggests configuring microbenchmark in a separate module. This would 22 // require any benchmarked code to be in a library module, not the :app module (see below). To avoid 23 // this requirement, we created the "benchmark" gradle property. 24 // 25 // For the most accurate results, the documentation recommends running tests on rooted devices with 26 // the CPU clock locked. 27 // 28 // See https://developer.android.com/studio/profile/benchmark#what-to-benchmark for when writing a 29 // jetpack microbenchmark is a good fit. 30 31 // I think `android` represents this object: 32 // https://google.github.io/android-gradle-dsl/3.3/com.android.build.gradle.AppExtension.html 33 ext.maybeConfigForJetpackBenchmark = { android -> 34 if (!project.hasProperty("benchmark")) { 35 return 36 } 37 38 // The official documentation https://developer.android.com/studio/profile/benchmark#full-setup 39 // recommends setting up the Microbenchmark library in a separate module from your app: AFAICT, 40 // the reason for this is to prevent the benchmarks from being configured against debug 41 // builds. We chose not to do this because it's a lot of work to pull code out into a 42 // separate module just to benchmark it. We were able to replicate the outcome by setting 43 // this testBuildType property. 44 android.testBuildType "nightly" 45 46 // WARNING: our proguard configuration for androidTest is not set up correctly so the tests 47 // fail if we don't disable minification. DISABLING MINIFICATION PRODUCES BENCHMARKS THAT ARE 48 // LESS REPRESENTATIVE TO THE USER EXPERIENCE, however, so we made this tradeoff to reduce 49 // implementation time. 50 project.ext.disableOptimization = true 51 52 android.defaultConfig { 53 // WARNING: the benchmark framework warns you if you're running the test in a configuration 54 // that will compromise the accuracy of the results. Unfortunately, I couldn't get everything 55 // working so I had to suppress some things. 56 testInstrumentationRunnerArguments = [ 57 58 // - ACTIVITY-MISSING: we're supposed to use the test instrumentation runner, 59 // "androidx.benchmark.junit4.AndroidBenchmarkRunner". However, when I do so, I get an error 60 // that we're unable to launch the activity. My understanding is that this runner will use an 61 // "IsolationActivity" to reduce the impact of other work on the device from affecting the benchmark 62 // and to opt into a lower-max CPU frequency on unrooted devices that support it 63 // - UNLOCKED: ./gradlew lockClocks, which locks the CPU frequency, fails on my device. See 64 // https://issuetracker.google.com/issues/176836267 for potential workarounds. 65 'androidx.benchmark.suppressErrors' : 'ACTIVITY-MISSING,UNLOCKED', 66 67 // The tests don't always output a JSON file with the data. To make sure it does, we have to 68 // set androidx.benchmark.output.enable to true. 69 'androidx.benchmark.output.enable' : 'true', 70 71 // We set the the output directory simply for simplicity since the benchmark_runner.py script 72 // can't know the name of the phone in the /build/outputs/ directory. The system defaults to 73 // {phone_name} which can be troublesome finding in some case. 74 // 75 // NOTE: Jetpack Benchmark outputs to Logcat too. However, the output in the logcat is 76 // the min of the several repeats, for more statistics. Therefore, to get more stats, 77 // we refer to the JSON file. 78 additionalTestOutputDir : '/storage/emulated/0/benchmark' 79 ] 80 } 81 }