BenchmarkRule


public final class BenchmarkRule implements TestRule


JUnit rule for benchmarking code on an Android device.

In Kotlin, benchmark with measureRepeated. In Java, use getState.

Benchmark results will be output:

  • Summary in Android Studio in the test log

  • In JSON format, on the host

  • In simple form in Logcat with the tag "Benchmark"

Every test in the Class using this @Rule must contain a single benchmark.

See the Benchmark Guide for more information on writing Benchmarks.

import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
import androidx.test.ext.junit.runners.AndroidJUnit4

@RunWith(AndroidJUnit4::class)
class MyBenchmark {
    @get:Rule val benchmarkRule = BenchmarkRule()

    @Test
    fun measureWork() {
        benchmarkRule.measureRepeated { doSomeWork() }
    }
}

Summary

Nested types

public final inner class BenchmarkRule.Scope extends MicrobenchmarkScope

Handle used for controlling measurement during measureRepeated.

Public methods

@NonNull Statement
apply(@NonNull Statement base, @NonNull Description description)
final @NonNull MicrobenchmarkConfig
final @NonNull BenchmarkState

Object used for benchmarking in Java.

Extension functions

final void

Benchmark a block of code.

final void

Benchmark a block of code, which runs on the main thread, and can safely interact with UI.

Public constructors

BenchmarkRule

Added in 1.0.0
public BenchmarkRule()

Public methods

apply

Added in 1.0.0
public @NonNull Statement apply(@NonNull Statement base, @NonNull Description description)

getConfig

Added in 1.4.0-alpha08
public final @NonNull MicrobenchmarkConfig getConfig()

getState

Added in 1.0.0
public final @NonNull BenchmarkState getState()

Object used for benchmarking in Java.

@Rule
public
BenchmarkRule benchmarkRule = new BenchmarkRule();

@Test
public
void myBenchmark() {
...
BenchmarkState state = benchmarkRule.getBenchmarkState();
while (state.keepRunning()) {
doSomeWork();
}
...
}
Throws
kotlin.IllegalStateException

if the BenchmarkRule isn't correctly applied to a test.

Extension functions

BenchmarkRuleKt.measureRepeated

public final void BenchmarkRuleKt.measureRepeated(
    @NonNull BenchmarkRule receiver,
    @ExtensionFunctionType @NonNull Function1<@NonNull BenchmarkRule.ScopeUnit> block
)

Benchmark a block of code.

import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
import androidx.test.ext.junit.runners.AndroidJUnit4

@RunWith(AndroidJUnit4::class)
class MyBenchmark {
    @get:Rule val benchmarkRule = BenchmarkRule()

    @Test
    fun measureWork() {
        benchmarkRule.measureRepeated { doSomeWork() }
    }
}
Parameters
@ExtensionFunctionType @NonNull Function1<@NonNull BenchmarkRule.ScopeUnit> block

The block of code to benchmark.

BenchmarkRuleKt.measureRepeatedOnMainThread

public final void BenchmarkRuleKt.measureRepeatedOnMainThread(
    @NonNull BenchmarkRule receiver,
    @ExtensionFunctionType @NonNull Function1<@NonNull BenchmarkRule.ScopeUnit> block
)

Benchmark a block of code, which runs on the main thread, and can safely interact with UI.

While @UiThreadRule works for a standard test, it doesn't work for benchmarks of arbitrary duration, as they may run for much more than 5 seconds and suffer ANRs, especially in continuous runs.

import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
import androidx.benchmark.junit4.measureRepeatedOnMainThread
import androidx.test.ext.junit.runners.AndroidJUnit4

@RunWith(AndroidJUnit4::class)
class MainThreadBenchmark {
    @get:Rule val benchmarkRule = BenchmarkRule()

    @Test
    fun measureWork() {
        benchmarkRule.measureRepeatedOnMainThread {
            // this block is run on the main thread
            doSomeWorkOnMainThread()
        }
    }
}
Parameters
@ExtensionFunctionType @NonNull Function1<@NonNull BenchmarkRule.ScopeUnit> block

The block of code to benchmark.

Throws
java.lang.Throwable

when an exception is thrown on the main thread.

kotlin.IllegalStateException

if a hard deadline is exceeded while the block is running on the main thread.