-
Notifications
You must be signed in to change notification settings - Fork 671
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve RealImageLoader.execute to properly call async request (#2205)
* Improve RealImageLoader.execute to properly call async request * Add experiments to get information about performance * Revert fix * Add comment what's blocking * Fix spotless * Tweak benchmarks + add traces Update benchmarks Experiment removing mutableState Before: AsyncImagePainter.onRememberedAverageMs min 0.1, median 0.1, max 0.1 AsyncImagePainter.onRememberedCount min 130.0, median 139.0, max 146.0 AsyncImagePainter.onRememberedMs min 9.3, median 12.5, max 16.3 frameDurationCpuMs P50 4.1, P90 9.1, P95 20.0, P99 99.3 After: AsyncImagePainter.onRememberedAverageMs min 0.1, median 0.1, max 0.1 AsyncImagePainter.onRememberedCount min 130.0, median 141.0, max 148.0 AsyncImagePainter.onRememberedMs min 8.3, median 10.5, max 15.8 frameDurationCpuMs P50 4.4, P90 8.6, P95 12.0, P99 95.1 Don't launch job for compose before AsyncImagePainter.onRememberedAverage_µs min 77.3, median 101.5, max 116.7 AsyncImagePainter.onRememberedCount min 130.0, median 130.0, max 146.0 AsyncImagePainter.onRemembered_µs min 10,048.4, median 13,880.2, max 16,900.0 timeToInitialDisplayMs min 256.8, median 281.7, max 358.9 frameDurationCpuMs P50 5.1, P90 9.2, P95 13.3, P99 117.0 after AsyncImagePainter.onRememberedAverage_µs min 68.9, median 78.7, max 91.1 AsyncImagePainter.onRememberedCount min 128.0, median 141.0, max 146.0 AsyncImagePainter.onRemembered_µs min 8,956.1, median 11,163.1, max 13,111.9 timeToInitialDisplayMs min 234.1, median 276.5, max 325.7 frameDurationCpuMs P50 4.5, P90 8.9, P95 15.5, P99 120.3 * Experiment removing Compose State Before: AsyncImagePainter.onRememberedAverageMs min 0.1, median 0.1, max 0.1 AsyncImagePainter.onRememberedCount min 130.0, median 139.0, max 146.0 AsyncImagePainter.onRememberedMs min 9.3, median 12.5, max 16.3 frameDurationCpuMs P50 4.1, P90 9.1, P95 20.0, P99 99.3 After: AsyncImagePainter.onRememberedAverageMs min 0.1, median 0.1, max 0.1 AsyncImagePainter.onRememberedCount min 130.0, median 141.0, max 148.0 AsyncImagePainter.onRememberedMs min 8.3, median 10.5, max 15.8 frameDurationCpuMs P50 4.4, P90 8.6, P95 12.0, P99 95.1 * Don't launch job for compose before AsyncImagePainter.onRememberedAverage_µs min 77.3, median 101.5, max 116.7 AsyncImagePainter.onRememberedCount min 130.0, median 130.0, max 146.0 AsyncImagePainter.onRemembered_µs min 10,048.4, median 13,880.2, max 16,900.0 timeToInitialDisplayMs min 256.8, median 281.7, max 358.9 frameDurationCpuMs P50 5.1, P90 9.2, P95 13.3, P99 117.0 after AsyncImagePainter.onRememberedAverage_µs min 68.9, median 78.7, max 91.1 AsyncImagePainter.onRememberedCount min 128.0, median 141.0, max 146.0 AsyncImagePainter.onRemembered_µs min 8,956.1, median 11,163.1, max 13,111.9 timeToInitialDisplayMs min 234.1, median 276.5, max 325.7 frameDurationCpuMs P50 4.5, P90 8.9, P95 15.5, P99 120.3 * Cleanup * Fix dependency with version catalog * Cleanup * Revert API changes
- Loading branch information
Showing
7 changed files
with
162 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
coil-benchmark/src/main/java/coil/benchmark/MicrosTraceSectionMetric.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package coil.benchmark | ||
|
||
import androidx.benchmark.macro.ExperimentalMetricApi | ||
import androidx.benchmark.macro.TraceMetric | ||
import androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi | ||
import androidx.benchmark.perfetto.PerfettoTraceProcessor | ||
|
||
/** | ||
* TraceSectionMetric to give average/sum in microseconds measurements. | ||
*/ | ||
@OptIn(ExperimentalMetricApi::class) | ||
class MicrosTraceSectionMetric( | ||
private val sectionName: String, | ||
private vararg val mode: Mode, | ||
private val label: String = sectionName, | ||
private val targetPackageOnly: Boolean = true, | ||
) : TraceMetric() { | ||
|
||
enum class Mode { | ||
Sum, | ||
Average | ||
} | ||
|
||
@ExperimentalPerfettoTraceProcessorApi | ||
@Suppress("RestrictedApi") | ||
override fun getResult( | ||
captureInfo: CaptureInfo, | ||
traceSession: PerfettoTraceProcessor.Session, | ||
): List<Measurement> { | ||
val slices = traceSession.querySlices( | ||
sectionName, | ||
packageName = if (targetPackageOnly) captureInfo.targetPackageName else null, | ||
) | ||
|
||
return mode.flatMap { m -> | ||
when (m) { | ||
Mode.Sum -> listOf( | ||
Measurement( | ||
name = sectionName + "_µs", | ||
// note, this duration assumes non-reentrant slices | ||
data = slices.sumOf { it.dur } / 1_000.0, | ||
), | ||
Measurement( | ||
name = sectionName + "Count", | ||
data = slices.size.toDouble(), | ||
), | ||
) | ||
|
||
Mode.Average -> listOf( | ||
Measurement( | ||
name = label + "Average_µs", | ||
data = slices.sumOf { it.dur } / 1_000.0 / slices.size, | ||
), | ||
) | ||
} | ||
} | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
coil-benchmark/src/main/java/coil/benchmark/ScrollBenchmark.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package coil.benchmark | ||
|
||
import android.graphics.Point | ||
import android.os.Build | ||
import androidx.annotation.RequiresApi | ||
import androidx.benchmark.macro.BaselineProfileMode | ||
import androidx.benchmark.macro.CompilationMode | ||
import androidx.benchmark.macro.FrameTimingMetric | ||
import androidx.benchmark.macro.StartupMode | ||
import androidx.benchmark.macro.StartupTimingMetric | ||
import androidx.benchmark.macro.junit4.MacrobenchmarkRule | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.uiautomator.By | ||
import coil.benchmark.BuildConfig.PROJECT | ||
import coil.benchmark.MicrosTraceSectionMetric.Mode.Average | ||
import coil.benchmark.MicrosTraceSectionMetric.Mode.Sum | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class ScrollBenchmark { | ||
|
||
@get:Rule | ||
val benchmarkRule = MacrobenchmarkRule() | ||
|
||
@RequiresApi(Build.VERSION_CODES.N) | ||
@Test | ||
fun baselineProfile() { | ||
benchmark(CompilationMode.Partial(BaselineProfileMode.Require)) | ||
} | ||
|
||
@Test | ||
fun fullCompilation() { | ||
benchmark(CompilationMode.Full()) | ||
} | ||
|
||
private fun benchmark(compilationMode: CompilationMode) { | ||
benchmarkRule.measureRepeated( | ||
packageName = "sample.$PROJECT", | ||
metrics = listOf( | ||
FrameTimingMetric(), | ||
StartupTimingMetric(), | ||
MicrosTraceSectionMetric( | ||
"rememberAsyncImagePainter", | ||
Sum, Average, | ||
), | ||
MicrosTraceSectionMetric( | ||
"AsyncImagePainter.onRemembered", | ||
Sum, Average, | ||
), | ||
), | ||
iterations = 20, | ||
startupMode = StartupMode.COLD, | ||
compilationMode = compilationMode, | ||
measureBlock = { | ||
startActivityAndWait() | ||
Thread.sleep(3_000) | ||
val list = device.findObject(By.res("list")) | ||
list.setGestureMargin(device.displayWidth / 5) | ||
list.drag(Point(list.visibleBounds.centerX(), list.visibleBounds.top)) | ||
Thread.sleep(300) | ||
}, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters