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
41
Gemini in Android Studio I/O extended 2024
veronikapj
0
360
앱 성능 영혼까지 끌어올리기
veronikapj
0
1k
Software Productivity - Devfest Songdo 2023
veronikapj
0
990
파이어베이스로 서비스 품질 올리기
veronikapj
0
340
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
Cursor/Devin全社導入の理想と現実
saitoryc
24
17k
API for docs
soutaro
3
1.4k
PHPで書いたAPIをGoに書き換えてみた 〜パフォーマンス改善の可能性を探る実験レポート〜
koguuum
0
180
メモリウォールを超えて:キャッシュメモリ技術の進歩
kawayu
0
1.9k
Boost Your Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
270
AIコーディングエージェントを 「使いこなす」ための実践知と現在地 in ログラス / How to Use AI Coding Agent in Loglass
rkaga
4
800
Dissecting and Reconstructing Ruby Syntactic Structures
ydah
2
1.2k
VitestのIn-Source Testingが便利
taro28
8
2.2k
Memory API : Patterns, Performance et Cas d'Utilisation
josepaumard
1
140
fieldalignmentから見るGoの構造体
kuro_kurorrr
0
110
個人開発の学生アプリが企業譲渡されるまで
akidon0000
0
1k
Unlock the Potential of Swift Code Generation
rockname
0
270
Featured
See All Featured
Docker and Python
trallard
44
3.3k
The Invisible Side of Design
smashingmag
299
50k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
Statistics for Hackers
jakevdp
798
220k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
The World Runs on Bad Software
bkeepers
PRO
68
11k
How to train your dragon (web standard)
notwaldorf
90
6k
Code Review Best Practice
trishagee
67
18k
A Tale of Four Properties
chriscoyier
158
23k
How STYLIGHT went responsive
nonsquared
100
5.5k
Writing Fast Ruby
sferik
628
61k
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