Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
How to use Macrobenchmark
Search
Veronikapj
July 20, 2024
Programming
0
310
How to use Macrobenchmark
Google I/O extended Android Korea 2024 에서 벤치마크 사용 설명서란 주제로 발표한 내용입니다.
https://festa.io/events/5509
Veronikapj
July 20, 2024
Tweet
Share
More Decks by Veronikapj
See All by Veronikapj
The Know-how of Seniors in the Age of AI
veronikapj
0
40
Gemini in Android Studio I/O extended 2024
veronikapj
0
360
앱 성능 영혼까지 끌어올리기
veronikapj
0
1k
Software Productivity - Devfest Songdo 2023
veronikapj
0
990
파이어베이스로 서비스 품질 올리기
veronikapj
0
330
What's new in Android IO23 Daejeon
veronikapj
1
280
KC23_Coroutine_Testing
veronikapj
0
160
ComposeCamp2022 Pathway2
veronikapj
1
390
io22 extended What's new in app performance
veronikapj
0
1k
Other Decks in Programming
See All in Programming
CRE Meetup!ユーザー信頼性を支えるエンジニアリング実践例の発表資料です
tmnb
0
620
Chrome Extension Techniques from Hell
moznion
1
160
タイムゾーンの奥地は思ったよりも闇深いかもしれない
suguruooki
1
510
新しいPHP拡張モジュールインストール方法「PHP Installer for Extensions (PIE)」を使ってみよう!
cocoeyes02
0
250
AI Agents with JavaScript
slobodan
0
210
DataStoreをテストする
mkeeda
0
280
SQL Server ベクトル検索
odashinsuke
0
160
OpenTelemetryを活用したObservability入門 / Introduction to Observability with OpenTelemetry
seike460
PRO
1
420
Building Scalable Mobile Projects: Fast Builds, High Reusability and Clear Ownership
cyrilmottier
2
240
AtCoder Heuristic First-step Vol.1 講義スライド
terryu16
3
1.1k
Rollupのビルド時間高速化によるプレビュー表示速度改善とバンドラとASTを駆使したプロダクト開発の難しさ
plaidtech
PRO
1
160
Django for Data Science (Boston Python Meetup, March 2025)
wsvincent
0
310
Featured
See All Featured
Producing Creativity
orderedlist
PRO
344
40k
Building Applications with DynamoDB
mza
94
6.3k
Making the Leap to Tech Lead
cromwellryan
133
9.2k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
12
650
Automating Front-end Workflow
addyosmani
1369
200k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
How GitHub (no longer) Works
holman
314
140k
Building Adaptive Systems
keathley
41
2.5k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7.2k
Gamification - CAS2011
davidbonilla
81
5.2k
Typedesign – Prime Four
hannesfritz
41
2.6k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Transcript
# Performance Macrobenchmark ࢎਊ ࢸݺࢲ ߓ | GDG Korea Android
ஏਸ ా೧ ୡӝ ࢿמਸ ࢸפ. ޙઁܳ ੌਵఃח ਗੋਸ ഛੋפ. ஏೞӝ
ਗੋ ঈ ࢿמ ޙઁܳ ೧Ѿೞח ߑߨ ഛੋೠ ղਊী ٮۄ ٘ܳ ࣻפ. ٘ ࣻ ࢿמਸ ஏೞҊ ୡӝ ࢿמҗ ࠺Үפ. ୡӝ ࢿמҗ ࠺Ү 🙆 Intro
Intro ٘ী ऀযח Unstable Parameters ܳ ݽف ୶ೞҊ ࣻೞ ݃ࣁਃ.
🙅 хਵ۽ ନ ݈ӝ! ೧ ஹನ࠶ ܻஹನ࣌ਸ ਬߊೞח গפݫ࣌ਸ ઁೞ݃ࣁਃ. хী ٮۄ ੍ӝ য۰ ୭ചܳ प೯ೞ ݃ࣁਃ.
ஏਸ ా೧ ୡӝ ࢿמਸ ࢸפ. ޙઁܳ ੌਵఃח ਗੋਸ ഛੋפ. ஏೞӝ
ਗੋ ঈ ࢿמ ޙઁܳ ೧Ѿೞח ߑߨ Intro ഛੋೠ ղਊী ٮۄ ٘ܳ ࣻפ. ٘ ࣻ ࢿמਸ ஏೞҊ ୡӝ ࢿמҗ ࠺Үפ. ୡӝ ࢿמҗ ࠺Ү
ࢿמ ޙઁܳ ખ ؊ औѱ ӝ ਤೠ ஏী ೠ ঠӝ
݃ߨ ইתפ. 🧙 # Performance
Intro জ ղࠗ ز ঌ ਃ হ UiAutomatorܳ ࢎ ਊ೧ࢲ
ࢿמਸ ஏפ. Jetpack Macrobenchmark ਬо ࠁח Ѫҗ э ࢿמਸ ഛੋפ. Performance ബҗ ஏਸ ਤೠ ୶ୌೞח ߑߨ ࢿמ ஏ पઁ ࢎਊ ജ҃ ࢿמ CIীࢲ प೯ ଵҊ : పझী ೠ ӝࠄੋ ೧
ޖਸ ஏ ೡ ࣻ աਃ? Intro জ दೡ ٸ৬
۽٘ ؼ ٸ ݃ա Ѧܻח Startup Timing 01 Frame Timing 02 Frameਸ ࢤࢿೞחؘ ݃ա Ѧܻח Trace Section 03 নೠ ஏਸ ೧ࠅ ࣻ ח ਊب API Memory Usage 04 জ ݃ա ݆ ݫݽܻܳ ࢎਊೞҊ ח Power 05 জ ݃ա ݆ ߓఠܻܳ ࣗݽೞҊ ח + https://developer.android.com/topic/performance/benchmarking/macrobenchmark-metrics
https://developer.android.com/codelabs/jetpack-compose-performance#0 Practical performance problem solving in Jetpack Compose ஏೞӝ
ஏೞӝ Macrobenchmark ݽٕ Macrobenchmarkח জ ٘৬ ܻ࠙ غয জ ஏ
పझ प೯ਸ ೞח com.android.test ݽٕ ਃפ.
ޖѢ Composable ୭ച ೞӝ ஏೞӝ
ஏೞӝ ஏ ҅ദ ࣁӝ • Layout Inspectorܳ ࢎਊ೧ࢲ ҳઑܳ ঈ
• п Layout ߹ दрਸ ஏ
ஏೞӝ Layout ҳઑ • Column : HeavyItem • PublishedText •
PublishDate.format • Layout : ImageDisplay • ImagePlaceHolder • ItemTag
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = "com.compose.performance", metrics = listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum) ), compilationMode = compilationMode, startupMode = StartupMode.WARM, iterations = 10, setupBlock = { setupBlock() }, measureBlock = { measureBlock() } ) } }
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() fun benchmark(compilationMode: CompilationMode) { } } class MacrobenchmarkRule : TestRule JUnit ӏਸ ࢎਊೞৈ গܻா࣌ द, झ܀݂ ژח গפݫ࣌җ э ӏݽ সਸ ߮݃ఊೞח ߑߨਸ ઁҕפ. https://developer.android.com/reference/kotlin/androidx/benchmark/macro/junit4/MacrobenchmarkRule
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = "com.compose.performance", metrics = listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum) ), compilationMode = compilationMode, startupMode = StartupMode.WARM, iterations = 10, setupBlock = { setupBlock() }, measureBlock = { measureBlock() } ) } }
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @Test fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) }
https://developer.android.com/reference/androidx/benchmark/macro/CompilationMode CompilationMode.Partial জ द ࢿמ ஏೞҊ ೧ೞחؘ ࢎਊ (Default) CompilationMode.Full জ प೯ runtime ࢿמ ࠺Ү ߂ ѐࢶ JIT ୭ച۽ ੋೠ ࢿמ ߸ز ਃੋ ઁѢ CompilationMode.None ࢎ ஹੌ হ. Baseline Pro fi le җ Benchmark ղীࢲ ࠺Ү CompilationMode
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = "com.compose.performance", metrics = listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum) ), compilationMode = compilationMode, startupMode = StartupMode.WARM, iterations = 10, setupBlock = { setupBlock() }, measureBlock = { measureBlock() } ) } }
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( .
. . startupMode = StartupMode.WARM, } Sta rt upMode https://developer.android.com/topic/performance/benchmarking/macrobenchmark-metrics StartupMode.COLD Sta rt up Benchmarkী ࢎਊ setupBlock৬ mesureBlock ࢎী জ ۽ࣁझ ઙܐ StartupMode.WARM Frame timing Benchmarkী ࢎਊ setupBlock റী ۽ࣁझо ઙܐغ ঋ ۽ࣁझܳ ઙܐೞ ঋҊ ݽٚ प೯ ੋ Activityܳ ײ Activity द ߑधҗ పझ द द ۽ࣁझ ࢚క ߸҃ StartupMode.HOT п Activity ߹ நय ݫழפ્ਸ ஏೞחؘ ࢎਊ ۽ࣁझ, ী प೯ ؍ Activityب द غ ঋ Null Macrobenchmark о ইޖѪب ೞ ঋח ݽ٘ killProcess() ۽ ஶ܀
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = "com.compose.performance", metrics = listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum) ), compilationMode = compilationMode, startupMode = StartupMode.WARM, iterations = 10, setupBlock = { setupBlock() }, measureBlock = { measureBlock() } ) } } SetupBlock ਗೞח ஏ ചݶ Frame ө ز (۽Ӓੋ ١)
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = "com.compose.performance", metrics = listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum) ), compilationMode = compilationMode, startupMode = StartupMode.WARM, iterations = 10, setupBlock = { setupBlock() }, measureBlock = { measureBlock() } ) } } MeasureBlock ஏਸ ਗೞח ز
MeasureBlock ஏਸ ਗೞח ز override fun MacrobenchmarkScope.measureBlock() { pressHome() startTaskActivity("accelerate_heavy")
device.wait( Until.hasObject(By.res("list_of_items")), 5_000) val feed = device.findObject(By.res("list_of_items")) feed.setGestureMargin(device.displayWidth / 5) repeat(2) { feed.drag( Point( feed.visibleCenter.x, feed.visibleBounds.top ) ) Thread.sleep(500) } }
MeasureBlock TestTagܳ ࠢৈࢲ ਗೞח resource ইоӝ @Composable fun ScreenContent(items: List<HeavyItem>)
{ LazyVerticalGrid( modifier = Modifier .fillMaxSize() .testTag(“list_of_items"), . . . ) { items(items) { item -> HeavyItem(item) } } } device.wait(Until.hasObject(By.res("list_of_items")), 5_000)
MeasureBlock TestTagܳ ࠢৈࢲ ਗೞח resource ইоӝ @Composable fun ScreenContent(items: List<HeavyItem>)
{ LazyVerticalGrid( modifier = Modifier .fillMaxSize() .testTag(“list_of_items"), . . . ) { items(items) { item -> HeavyItem(item) } } } device.wait(Until.hasObject(By.res("list_of_items")), 5_000)
MeasureBlock ஏਸ ਗೞח ز - झ܀ override fun MacrobenchmarkScope.measureBlock() {
pressHome() startTaskActivity("accelerate_heavy") device.wait( Until.hasObject(By.res("list_of_items")), 5_000) val feed = device.findObject(By.res("list_of_items")) feed.setGestureMargin(device.displayWidth / 5) repeat(2) { feed.drag( Point( feed.visibleCenter.x, feed.visibleBounds.top ) ) Thread.sleep(500) } }
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test
fun accelerateHeavyScreenCompilation() = benchmark(CompilationMode.Partial()) fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = "com.compose.performance", metrics = listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum) ), compilationMode = compilationMode, startupMode = StartupMode.WARM, iterations = 10, setupBlock = { setupBlock() }, measureBlock = { measureBlock() } ) } } ஏ ೦ݾ https://developer.android.com/topic/performance/benchmarking/macrobenchmark-metrics
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( .
. . metrics = listOf( FrameTimingMetric() . . .), } frameDurationCpuMs P50 11.9, P90 24.0, P95 30.3, P99 90.6 frameOverrunMs P50 3.5, P90 21.2, P95 25.9, P99 252.0 FrameTimingMetric 👉 CPUীࢲ UI झۨ٘৬ RenterThreadীࢲ ۨ ࢤࢿغחؘ Ѧܽ दр https://developer.android.com/topic/performance/benchmarking/macrobenchmark-metrics
@RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( .
. . metrics = listOf( FrameTimingMetric() . . .), } frameDurationCpuMs P50 11.9, P90 24.0, P95 30.3, P99 90.6 frameOverrunMs P50 3.5, P90 21.2, P95 25.9, P99 252.0 FrameTimingMetric 👉 CPUীࢲ UI झۨ٘৬ RenterThreadীࢲ ۨ ࢤࢿغחؘ Ѧܽ दр 👉 য ۨ ӝೠਸ ֈӟ दр +(নࣻ)ੌ ࣻ۾ ߡߢѢܿ, - (ࣻ)ח ݃ա ࡅܲ Android 12(API 31) https://developer.android.com/topic/performance/benchmarking/macrobenchmark-metrics
ஏೞӝ TraceSection Metric • Column : HeavyItem • PublishedText •
PublishDate.format • Layout : ImageDisplay • ImagePlaceHolder • ItemTag Layout ҳઑ ߹۽ ࢸ
listOf( FrameTimingMetric(), TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum), TraceSectionMetric("PublishedText", TraceSectionMetric.Mode.Sum), TraceSectionMetric("PublishDate.format", TraceSectionMetric.Mode.Sum), TraceSectionMetric("ImageDisplay", TraceSectionMetric.Mode.Sum),
TraceSectionMetric("ImagePlaceholder", TraceSectionMetric.Mode.Sum), TraceSectionMetric("ItemTag", TraceSectionMetric.Mode.Sum) ) @RunWith(AndroidJUnit4::class) class HeavyScreenBenchmark { fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( . . . metrics = listOf(FrameTimingMetric(). . .), } TraceSectionMetric Trace Section ઁҕػ sectionName җ ੌೞח പࣻ৬ ࣗਃػ दр ୭ࣗदр, ঔ ч, ୭ दр (ms) h tt ps://developer.android.com/topic/pe rf ormance/benchmarking/macrobenchmark-metrics?hl=ko#trace-section
TraceSectionMetric.Mode TraceSectionMetric("HeavyItem", TraceSectionMetric.Mode.Sum), https://developer.android.com/reference/androidx/benchmark/macro/TraceSectionMetric.Mode Mode.First SectionName ੌೞח ߣ૩ ࣂ࣌ instance
ࣗਃदр Mode.Sum SectionName ੌೞח ݽٚ ࣂ࣌ instance ࣗਃ दр ҅ Mode.Max SectionName ੌೞח ࣂ࣌ о ч ӝ۾ Mode.Min SectionName ੌೞח ࣂ࣌ о ч ӝ۾ Mode.Average SectionName ੌೞח ࣂ࣌ ಣӐ Mode.Count SectionName ੌೞח ࣂ࣌ ѐࣻ 1.3.0 beta+ 1.3.0 beta+ 1.3.0 beta+ 1.3.0 beta+
ஏೞӝ _count : SectionName җ ੌೞח іࣻ _ms : Section
ஏػ ࣗਃ दр TraceSectionMetric ஏ Ѿҗ
ஏೞӝ HeavyItem PublishedText PublishDate.format ImageDisplay ImagePlaceHolder ItemTag Min Median Max
HeavyItem 46.4 50.2 53.0 PublishedText 6.9 7.7 8.6 PublishDate.format 0.7 0.8 0.9 ImageDisplay 27.1 29.1 30.4 ImagePlaceHolder 17.4 18.6 19.3 ItemTag 2.7 3.6 5.4 TraceSectionMetric ஏ Ѿҗ
System Trace ࠁ۞оӝ ਗੋঈ Test Resultsীࢲ Ѿҗ link ࠗ࠙ ܼ
Trace ੌ ਤ Measure > build > outputs > connected_android_text_additional_output
> benchmarkRelease > connected > ‘connected device’ ਗੋঈ
ਗੋঈ Pro fi ler System Trace
উ٘۽٘ झౚ٣য় प೯ ਃ হ ٣߄झ Threadܳ ࠅ ࣻ
Trace , प೯غח SQL quries ਗੋঈ Web-based tool Gives you whole picture https://youtu.be/Z96wfbID_Yc?si=pOe8w7hT7IEbsnb-&t=655 Investigate deeper H tt ps://ui.pe rf e tt o.dev/
ਗੋঈ Pe rf e tt o
ਗੋঈ Expected Timeline दझమীࢲ ۨ ࢤࢿೞח ࢚ ఋۄੋ
ਗੋঈ Actual Timeline ࢚ࠁ য়ې Ѧ۰ࢲ ࢤࢿػ ۨ पઁ۽ ۨ
ࢤࢿػ दр
ਗੋঈ System-tracing call cha r दр ইې ഐػ ೣࣻ
ࣗਃ दр ୨ Trace Code Untrace Code
ਗੋঈ о য়ې Ѧܻח স ࠙ࢳೞӝ HeavyItem ࣗਃ दр
ਗੋঈ о ݆ ରೞח दр ImageDisplay о য়ې Ѧܻח স
࠙ࢳೞӝ
ਗੋঈ Image ۽٘ೞחؘ Placeholder о о য়ې Ѧܻ֎?? о য়ې
Ѧܻח স ࠙ࢳೞӝ
ਗੋঈ https://developer.android.com/develop/ui/compose/tooling/tracing दػ ݅ ୶ য়ߡ٘о Ҋ জ ࢿמী
ೱਸ ঋ জ ݽٚ ೣࣻ ഐਸ ୶ জ ࢿמী ೱਸ ݅ ߊࢤೞ ח ࢚ട, ഐغח ೣࣻ, ഐ ࠼بܳ ਵ۽ ঈ Composition function ನೣغয ঋ Composition function ನೣ Composition Tracing +
// :app module implementation( “androidx.compose.runtime:runtime-tracing:1.0.0-beta01" ) https://developer.android.com/develop/ui/compose/tooling/tracing // :mesure module
implementation( “androidx.tracing:tracing-perfetto:1.0.0") implementation( "androidx.tracing:tracing-perfetto-binary:1.0.0") // gradle configuration androidx.benchmark.fullTracing.enable=true
ਗੋঈ Composition function ҙ оמ
ImagePlaceHolder ѐࢶ 1. ܳ ࠺زӝ۽ ۽٘ 2. ؊ ࡈܻ ۽٘غب۾
ࢎਊ 3. ਃೠ ӝী ٮۄ ઑغח Vector Drawable ࢎਊ ٘ࣻ
1600 x 1600 px @Composable fun imagePlaceholder() = trace("ImagePlaceholder") {
painterResource(R.drawable.placeholder) } ٘ࣻ
@Composable fun imagePlaceholder() = trace("ImagePlaceholder") { painterResource(R.drawable.placeholder_vector) } placeholder_vector.xml ٘ࣻ
TraceSectionMetric ஏ Ѿҗ ୡӝ ࢿמҗ ࠺Ү
ѐࢶ Ѿҗ Before A ft er Max ӝળ 19.3 ীࢲ
4.4 ۽ 77.2% хࣗ ୡӝ ࢿמҗ ࠺Ү
Before A ft er ୡӝ ࢿמҗ ࠺Ү
ஏਸ ా೧ ୡӝ ࢿמਸ ࢸפ. ޙઁܳ ੌਵఃח ਗੋਸ ഛੋפ. ஏೞӝ
ਗੋ ঈ ࢿמ ޙઁܳ ೧Ѿೞח ߑߨ ഛੋೠ ղਊী ٮۄ ٘ܳ ࣻפ. ٘ ࣻ ࢿמਸ ஏೞҊ ୡӝ ࢿמҗ ࠺Үפ. ୡӝ ࢿמҗ ࠺Ү 🙆 Intro
ஏਸ ా೧ ୡӝ ࢿמਸ ࢸפ. ޙઁܳ ੌਵఃח ਗੋਸ ഛੋפ. ஏೞӝ
ਗੋ ঈ ഛੋೠ ղਊী ٮۄ ٘ܳ ࣻפ. ٘ ࣻ ࢿמਸ ஏೞҊ ୡӝ ࢿמҗ ࠺Үפ. ୡӝ ࢿמҗ ࠺Ү ܻ Macrobenchmark ࢸೞӝ ஏ чٜ ঌইࠁӝ Ѿҗ ч ࠺Үೞӝ Profiler ژח Perfetto chart ೧ೞӝ ޖѢ স оߺѱ ѐࢶೞӝ ࣻ റ ബҗо ח ࠺Үೞӝ
хࢎפ. ߓ veronikapj GDG Korea Android Resources https://developer.android.com/codelabs/jetpack-compose-performance