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
330
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
Google I/O 요약만 봤다고? AI가 못 보는 진짜 이야기
veronikapj
0
16
The Know-how of Seniors in the Age of AI
veronikapj
0
58
Gemini in Android Studio I/O extended 2024
veronikapj
0
390
앱 성능 영혼까지 끌어올리기
veronikapj
0
1.1k
Software Productivity - Devfest Songdo 2023
veronikapj
0
1k
파이어베이스로 서비스 품질 올리기
veronikapj
0
360
What's new in Android IO23 Daejeon
veronikapj
1
290
KC23_Coroutine_Testing
veronikapj
0
160
ComposeCamp2022 Pathway2
veronikapj
1
400
Other Decks in Programming
See All in Programming
PHPUnitの限界をPlaywrightで補完するテストアプローチ
yuzneri
0
330
Quality Gates in the Age of Agentic Coding
helmedeiros
PRO
1
110
PHPカンファレンス関西2025 基調講演
sugimotokei
5
950
202507_ADKで始めるエージェント開発の基本 〜デモを通じて紹介〜(奥田りさ)
risatube
PRO
5
1.2k
Googleの新しいコーディングAIエージェントJulesを使ってみた
tonionagauzzi
0
130
リバースエンジニアリング新時代へ! GhidraとClaude DesktopをMCPで繋ぐ/findy202507
tkmru
4
1.3k
NEWT Backend Evolution
xpromx
1
150
AIともっと楽するE2Eテスト
myohei
9
3.1k
[SRE NEXT] 複雑なシステムにおけるUser Journey SLOの導入
yakenji
0
800
Hack Claude Code with Claude Code
choplin
8
2.8k
TypeScriptでDXを上げろ! Hono編
yusukebe
3
870
Streamlitで実現できるようになったこと、実現してくれたこと
ayumu_yamaguchi
2
220
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
Rebuilding a faster, lazier Slack
samanthasiow
83
9.1k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Site-Speed That Sticks
csswizardry
10
720
BBQ
matthewcrist
89
9.7k
Automating Front-end Workflow
addyosmani
1370
200k
Speed Design
sergeychernyshev
32
1k
Java REST API Framework Comparison - PWX 2021
mraible
31
8.7k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
The Cult of Friendly URLs
andyhume
79
6.5k
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