diff options
Diffstat (limited to 'docs/html-intl/intl/ko/preview/testing/performance.jd')
-rw-r--r-- | docs/html-intl/intl/ko/preview/testing/performance.jd | 656 |
1 files changed, 656 insertions, 0 deletions
diff --git a/docs/html-intl/intl/ko/preview/testing/performance.jd b/docs/html-intl/intl/ko/preview/testing/performance.jd new file mode 100644 index 0000000..ce2bf27 --- /dev/null +++ b/docs/html-intl/intl/ko/preview/testing/performance.jd @@ -0,0 +1,656 @@ +page.title=표시 성능 테스트 +page.image=images/cards/card-test-performance_2x.png +page.keywords=성능, FPS, 도구 + +@jd:body + + +<div id="qv-wrapper"> + <div id="qv"> + <h2>이 문서의 내용</h2> + <ol> + <li><a href="#measure">UI 성능 측정</a> + <ul> + <li><a href="#aggregate">프레임 상태 집계</a></li> + <li><a href="#timing-info">정확한 프레임 타이밍 정보</a></li> + <li><a href="#timing-dump">단순한 프레임 타이밍 덤프</a></li> + <li><a href="#collection-window">상태 수집 창 제어</a></li> + <li><a href="#diagnose">성능 저하 진단</a></li> + <li><a href="#resources">추가 리소스</a></li> + </ul> + </li> + <li><a href="#automate">UI 성능 테스트 자동화</a> + <ul> + <li><a href="#ui-tests">UI 테스트 설정</a></li> + <li><a href="#automated-tests">자동화된 UI 테스트 설정</a></li> + <li><a href="#triage">관측된 문제 심사 및 수정</a></li> + </ul> + </li> + </ol> + </div> +</div> + + +<p> + 사용자 인터페이스(UI) 성능 테스트를 수행하면 앱이 기능적인 요건에 부합할 뿐만 아니라 사용자가 앱과 부드럽고 매끈하게 상호작용하며 초당 60 프레임의 일관된 속도로(<a href="https://www.youtube.com/watch?v=CaMTIgxCSqU&index=25&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">왜 60fps일까요?</a>) 생략되거나 지연된 프레임, 또는 전문 용어로 <em>jank</em>(프레임이 넘어가는 현상)가 없이 실행되게 보장할 수 있습니다. + + + 이 문서에서는 UI 성능을 측정하는 데 사용할 수 있는 몇 가지 도구를 설명하고, 테스트 방법에 UI 성능 측정법을 통합하는 데 쓰이는 접근법을 보여드립니다. + + +</p> + + +<h2 id="measure">UI 성능 측정</h2> + +<p> + 성능을 개선하려면 우선 시스템의 성능을 측정할 수 있는 능력부터 갖추고, 그 다음에 파이프라인의 여러 부분에서 나올 수 있는 다양한 문제를 진단하고 식별해야 합니다. + + +</p> + +<p> + <em><a href="https://source.android.com/devices/tech/debug/dumpsys.html">dumpsys</a></em>는 Android 도구의 일종으로 기기에서 실행되면서 시스템 서비스의 상태에 대한 흥미로운 정보를 덤프하는 역할을 합니다. + + <em>gfxinfo</em> 명령을 dumpsys에 전달하면 기록 단계 중에 발생하는 애니메이션 프레임과 관련된 성능 정보가 담긴 logcat으로 출력을 제공합니다. + + +</p> + +<pre> +> adb shell dumpsys gfxinfo <PACKAGE_NAME> +</pre> + +<p> + 이 명령은 프레임 타이밍 데이터의 서로 다른 변형을 여러 개 작성할 수 있습니다. +</p> + +<h3 id="aggregate">프레임 상태 집계</h3> + +<p> + M 미리 보기에서 이 명령은 프레임 데이터의 집계된 분석을 logcat으로 출력합니다. 이는 프로세스의 전 수명을 통틀어 수집한 것입니다. + 예를 들면 다음과 같습니다. +</p> + +<pre class="noprettyprint"> +Stats since: 752958278148ns +Total frames rendered: 82189 +Janky frames: 35335 (42.99%) +90th percentile: 34ms +95th percentile: 42ms +99th percentile: 69ms +Number Missed Vsync: 4706 +Number High input latency: 142 +Number Slow UI thread: 17270 +Number Slow bitmap uploads: 1542 +Number Slow draw: 23342 +</pre> + +<p> + 이와 같은 높은 레벨의 통계는 레벨이 높을 때 앱의 렌더링 성능을 나타내며, 이외에도 여러 프레임에 걸친 앱의 안정성을 나타내기도 합니다. + +</p> + + +<h3 id="timing-info">정확한 프레임 타이밍 정보</h3> + +<p> + M 미리 보기에서는 gfxinfo에 사용할 수 있는 새 명령어를 도입했습니다. 바로 <em>framestats</em>로, 이는 최근 프레임으로부터 극히 상세한 프레임 타이밍 정보를 제공하여 문제를 더욱 정확하게 추적하고 디버그할 수 있습니다. + + +</p> + +<pre> +>adb shell dumpsys gfxinfo <PACKAGE_NAME> framestats +</pre> + +<p> + 이 명령은 프레임 타이밍 정보를 나노초 타임스탬프로 출력하며, 그 출처는 앱이 만든 마지막 120개의 프레임입니다. 아래는 adb dumpsys gfxinfo + <PACKAGE_NAME> framestats에서 가져온 원시 출력을 예로 나타낸 것입니다. + +</p> + +<pre class="noprettyprint"> +0,49762224585003,49762241251670,9223372036854775807,0,49762257627204,49762257646058,49762257969704,49762258002100,49762265541631,49762273951162,49762300914808,49762303675954, +0,49762445152142,49762445152142,9223372036854775807,0,49762446678818,49762446705589,49762447268818,49762447388037,49762453551527,49762457134131,49762474889027,49762476150120, +0,49762462118845,49762462118845,9223372036854775807,0,49762462595381,49762462619287,49762462919964,49762462968454,49762476194547,49762476483454,49762480214964,49762480911527, +0,49762479085548,49762479085548,9223372036854775807,0,49762480066370,49762480099339,49762481013089,49762481085850,49762482232152,49762482478350,49762485657620,49762486116683, +</pre> + +<p> + 이 출력의 각 줄은 앱이 만든 프레임을 나타냅니다. 각 줄에는 정해진 숫자의 열이 있으며 이 열은 프레임 제작 파이프라인의 각 단계에서 소요한 시간을 나타냅니다. + 다음 섹션에서는 각 열이 무엇을 나타내는지 등, 이 형식에 대해 좀 더 자세히 다뤄보겠습니다. + +</p> + + +<h4 id="fs-data-format">Framestats 데이터 형식</h4> + +<p> + 데이터 블록은 CSV 형식으로 출력되기 때문에 이를 개발자가 선택한 스프레드시트 도구에 붙여넣거나 수집해서 스크립트로 구문 분석하기 등의 작업이 매우 단도직입적입니다. + 다음 표는 출력 데이터 열의 형식을 설명한 것입니다. + 타임스탬프는 모두 나노초 단위입니다. +</p> + +<ul> + <li>플래그 + <ul> + <li>플래그 열에 '0'이 기재되어 있는 행의 경우, 총 프레임 시간을 계산하려면 FRAME_COMPLETED 열에서 INTENDED_VSYNC 열을 빼면 됩니다. + + </li> + + <li>이것이 0이 아니면 그 행은 무시해야 합니다. 해당 프레임이 정상 성능의 이상값인 것으로 판별되었기 때문이며, 여기에서는 레이아웃과 그리기에 16ms 이상이 걸릴 것으로 예상됩니다. + + 다음은 이런 일이 일어나는 몇 가지 이유입니다. + <ul> + <li>창 레이아웃이 변경되었습니다(애플리케이션의 첫 프레임 또는 한 회 회전 이후). + + </li> + + <li>프레임을 건너뛰었을 가능성도 있습니다. 이 경우 몇몇 값에 가비지 타임스탬프가 있을 것입니다. + 프레임을 건너뛰는 것은 해당 프레임이 60fps를 초과하는 경우 또는 화상에 나타난 것 중 아무 것도 변한 것이 없을 때 등이며, 이는 반드시 앱에 문제가 있음을 나타내는 징후는 아닙니다. + + + </li> + </ul> + </li> + </ul> + </li> + + <li>INTENDED_VSYNC + <ul> + <li>프레임에 대한 원래 의도한 시작 지점입니다. 이 값이 VSYNC와 다른 경우, UI 스레드에서 발생한 작업이 있어 이것이 vsync 신호에 적절한 시간 내에 응답하지 못하도록 한 것입니다. + + + </li> + </ul> + </li> + + <li>VSYNC + <ul> + <li>Vsync 수신기 전체와 프레임에 대한 드로잉에서 사용된 시간 값입니다.(Choreographer 프레임 콜백, 애니메이션, View.getDrawingTime() 등) + + </li> + + <li>VSYNC와 이것이 애플리케이션에 미치는 영향에 대해 더 자세히 알아보려면 <a href="https://www.youtube.com/watch?v=1iaHxmfZGGc&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=23">VSYNC 이해하기</a> 비디오를 확인하십시오. + + + </li> + </ul> + </li> + + <li>OLDEST_INPUT_EVENT + <ul> + <li>입력 대기열에서 가장 오래된 입력 이벤트의 타임스탬프 또는 프레임에 대한 입력 이벤트가 없는 경우 Long.MAX_VALUE입니다. + + </li> + + <li>이 값은 기본적으로 플랫폼 작업을 위해 의도된 것이며 앱 개발자에게는 한정된 정도로 유용한 값입니다. + + </li> + </ul> + </li> + + <li>NEWEST_INPUT_EVENT + <ul> + <li>입력 대기열에서 가장 최근 입력 이벤트의 타임스탬프 또는 프레임에 대한 입력 이벤트가 없는 경우 Long.MAX_VALUE입니다. + + </li> + + <li>이 값은 기본적으로 플랫폼 작업을 위해 의도된 것이며 앱 개발자에게는 한정된 정도로 유용한 값입니다. + + </li> + + <li>다만 앱이 얼마나 긴 대기 시간을 추가하고 있는지를 대략적으로 알아볼 수는 있습니다. (FRAME_COMPLETED - NEWEST_INPUT_EVENT)를 살펴보면 됩니다. + + </li> + </ul> + </li> + + <li>HANDLE_INPUT_START + <ul> + <li>입력 이벤트가 애플리케이션에 발송된 시점의 타임스탬프입니다. + </li> + + <li>이것과 ANIMATION_START 사이의 시간을 보면 애플리케이션이 입력 이벤트를 처리하느라 보낸 시간을 측정할 수 있습니다. + + </li> + + <li>이 숫자가 크면(2ms 초과) 이는 앱이 입력 이벤트를 처리하느라 보기 드물게 긴 시간을 소요한다는 뜻입니다. 예를 들어 View.onTouchEvent()는 이 작업을 최적화해야 하거나 다른 스레드로 오프로드해야 한다는 뜻일 수 있습니다. + + 다른 시나리오도 몇 가지 있을 수 있다는 점을 유의하십시오. 예를 들어 새 액티비티를 시작하는 클릭 이벤트나 그와 비슷한 것의 경우, 이 숫자가 클 것을 예상하고 받아들일 수 있습니다. + + + </li> + </ul> + </li> + + <li>ANIMATION_START + <ul> + <li>Choreographer에 등록된 애니메이션이 실행된 시점의 타임스탬프입니다. + </li> + + <li>이것과 PERFORM_TRANVERSALS_START 사이의 시간을 보면 실행 중인 애니메니터 전체((ObjectAnimator, ViewPropertyAnimator 및 Transitions가 보편적인 것들임)를 평가하는 데 시간이 얼마나 걸렸는지 판단할 수 있습니다. + + + </li> + + <li>이 숫자가 크면(2ms 초과), 앱이 사용자 지정 애니메이터를 작성한 적이 있는지 확인하십시오. 아니면 ObjectAnimators가 애니메이션 효과를 실행하는 필드가 어느 것인지 알아보고 이들이 애니메이션에 대해 적절한지 확인해야 합니다. + + + </li> + + <li>Choreographer에 대한 자세한 정보는 <a href="https://developers.google.com/events/io/sessions/325418001">버터거나 나쁘거나(For Butter or Worse)</a> 비디오를 참조하십시오. + + </li> + </ul> + </li> + + <li>PERFORM_TRAVERSALS_START + <ul> + <li>이 값에서 DRAW_START를 빼면 레이아웃과 측정 단계를 완료하는 데 얼마나 걸렸는지 추출할 수 있습니다(스크롤 또는 애니메이션 중에는 이 값이 0에 가까울 것이라는 예상이 나와야 한다는 점을 유의하십시오). + + + </li> + + <li>렌더링 파이프라인의 측정 및 레이아웃 단계에 대한 자세한 정보는 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27">무효화, 레이아웃 및 성능</a> 비디오를 참조하십시오. + + + </li> + </ul> + </li> + + <li>DRAW_START + <ul> + <li>PerformTraversals의 그리기 단계가 시작된 시점입니다. 이것은 무효화된 모든 보기의 표시 목록을 기록하는 시작 지점입니다. + + </li> + + <li>이것과 SYNC_START 사이의 시간이 트리의 모든 무효화된 보기에서 View.draw()를 호출하는 데 걸린 시간입니다. + + </li> + + <li>드로잉 모델에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#hardware-model">하드웨어 가속</a> 또는 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27">무효화, 레이아웃 및 성능</a> 비디오를 참조하십시오. + + + </li> + </ul> + </li> + + <li>SYNC_START + <ul> + <li>드로잉의 동기화 단계가 시작된 시점입니다. + </li> + + <li>이것과 ISSUE_DRAW_COMMANDS_START 사이의 시간이 상당히 큰 값인 경우(0.4ms 초과 또는 그와 유사), 일반적으로 새로운 비트맵이 많이 그려져서 이를 GPU에 업로드해야 한다는 뜻입니다. + + + </li> + + <li>동기화 단계에 대해 더 자세히 알아보려면 <a href="https://www.youtube.com/watch?v=VzYkVL1n4M8&index=24&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu">프로필 GPU 렌더링</a> 비디오를 참조하십시오. + + </li> + </ul> + </li> + + <li>ISSUE_DRAW_COMMANDS_START + <ul> + <li>하드웨어 렌더러가 GPU에 드로잉 명령을 발행하기 시작한 시점입니다. + </li> + + <li>이것과 FRAME_COMPLETED 사이의 시간을 보면 앱이 얼마나 많은 GPU 작업을 생성하고 있는지 대략적으로 알 수 있습니다. + Overdraw가 너무 많거나 렌더링 효과가 비효율적인 것 등의 문제가 여기에 나타납니다. + + </li> + </ul> + </li> + + <li>SWAP_BUFFERS + <ul> + <li>EglSwapBuffers가 호출된 시점으로, 플랫폼 작업 외에는 비교적 흥미롭지 않습니다. + + </li> + </ul> + </li> + + <li>FRAME_COMPLETED + <ul> + <li>모두 끝났습니다! 이 프레임에 작업하느라 소요된 총 시간을 계산하려면 FRAME_COMPLETED - INTENDED_VSYNC를 수행하면 됩니다. + + </li> + </ul> + </li> + +</ul> + +<p> + 이 데이터는 여러 가지 방법으로 사용할 수 있습니다. 한 가지 단순하면서도 유용한 시각화는 프레임 시간의 분배(FRAME_COMPLETED - INTENDED_VSYNC)를 여러 가지 대기 시간 버킷에서 표시한 히스토그램을 예로 들 수 있습니다. 아래 그림을 참조하십시오. + + 이 그래프를 보면 한 눈에 대부분의 프레임이 아주 양호했다는 것을 알아볼 수 있습니다. 대부분 16ms 최종 기한(빨간색으로 표시)보다 한참 아래에 있지만, 최종 기한을 크게 넘어선 프레임도 몇 개 있습니다. + + 이 히스토그램에서 시간 경과에 따른 변화를 살펴보면 대규모 이동이나 새 이상값이 생성되는 것을 확인할 수 있습니다. + 이외에도 데이터 내의 수많은 타임스탬프를 근거로 입력 대기 시간, 레이아웃에서 보낸 시간 또는 여타 비슷한 흥미로운 메트릭도 그래프로 표현할 수 있습니다. + + +</p> + +<img src="{@docRoot}preview/images/perf-test-framestats.png"> + + +<h3 id="timing-dump">단순한 프레임 타이밍 덤프</h3> + +<p> + <strong>프로필 GPU 렌더링</strong>이 개발자 옵션에서 <strong>adb 셸의 dumpsys gfxinfo</strong>로 설정된 경우, <code>adb shell dumpsys gfxinfo</code> 명령이 가장 최근의 120개 프레임에 대한 타이밍 정보를 출력하되, 몇 개의 서로 다른 카테고리로 나누어 탭으로 구분된 값을 담아 표현합니다. + + + 이 데이터를 사용하면 드로잉 파이프라인의 어떤 부분이 레벨이 높을 때 느려지는지 나타내는 데 유용합니다. + +</p> + +<p> + 위의 <a href="#fs-data-format">framestats</a>와 마찬가지로, 이것을 개발자가 선택한 스프레드시트 도구에 붙여넣거나 수집해서 스크립트로 구문 분석하는 작업은 매우 단도직입적입니다. + + 다음 그래프는 앱이 생성한 수많은 프레임이 어디에서 시간을 보내는지 분석한 내용을 표시한 것입니다. + +</p> + +<img src="{@docRoot}preview/images/perf-test-frame-latency.png"> + +<p> + Gfxinfo를 실행한 결과, 그 출력을 복사하여 이를 스프레드시트 애플리케이션에 붙여넣은 다음 데이터를 누적 가로 막대형 그래프로 나타내는 것입니다. + +</p> + +<p> + 각 세로 막대는 애니메이션 한 프레임을 나타냅니다. 그 막대의 높이가 해당 애니메이션 프레임을 계산하는 데 걸린 밀리초 수를 나타냅니다. + 막대에서 색이 지정된 각 세그먼트는 렌더링 파이프라인의 각기 다른 단계를 나타내므로, 개발자는 이것을 보고 애플리케이션의 어떤 부분이 병목 현상을 유발하고 있는지 확인할 수 있습니다. + + 렌더링 파이프라인을 잘 이해하고 이에 맞게 최적화하는 법에 대한 자세한 내용은 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&index=27&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">무효화 레이아웃 및 성능</a> 비디오를 참조하십시오. + + +</p> + + +<h3 id="collection-window">상태 수집 창 제어</h3> + +<p> + Framestats와 단순한 프레임 타이밍은 양쪽 모두 아주 짧은 시간 범위 동안 데이터를 수집합니다. 렌더링 약 2초에 상당하는 시간입니다. + 이 시간 범위를 정확하게 제어하려면(예: 데이터를 특정 애니메이션에 제한), 카운터를 모두 초기화한 다음 수집한 통계를 집계하면 됩니다. + + +</p> + +<pre> +>adb shell dumpsys gfxinfo <PACKAGE_NAME> reset +</pre> + +<p> + 이 방법은 명령 자체를 덤프하는 방법과 함께 써서 정기적인 간격을 두고 수집과 초기화를 반복하여 계속해서 2초 미만의 프레임 창을 캡처하도록 하는 데 쓰일 수도 있습니다. + + +</p> + + +<h3 id="diagnose">성능 저하 진단</h3> + +<p> + 성능이 저하된 것을 알아내는 것은 문제를 추적하고 애플리케이션의 건강 상태를 높은 수준으로 유지 관리하는 데 좋은 첫 단계입니다. + 그러나 dumpsys는 문제의 존재 여부와 상대적인 심각도만 식별하는 데 그치지 않습니다. + 각 성능 문제의 제각기 다른 원인을 진단하고 이를 해결하기 위해 적절한 방법을 찾아야 하는 것은 변하지 않습니다. + 이를 위해, <a href="{@docRoot}tools/help/systrace.html">systrace</a> 도구를 사용하는 것을 적극적으로 추천합니다. + +</p> + + +<h3 id="resources">추가 리소스</h3> + +<p> + Android의 렌더링 파이프라인의 작동 원리나 여기에서 마주칠 수 있는 보편적인 문제와 그 해결 방법에 대한 자세한 정보를 원하시면, 다음 리소스 중 몇 가지를 유용하게 쓸 수 있습니다. + + +</p> + +<ul> + <li>렌더링 성능의 기초 + </li> + <li>왜 60fps일까요? + </li> + <li>Android UI와 GPU + </li> + <li>무효화 레이아웃 및 성능 + </li> + <li>Systrace로 UI 성능 분석하기 + </li> +</ul> + + +<h2 id="automate">UI 성능 테스트 자동화</h2> + +<p> + UI 성능 테스트에 대한 한 가지 관점은 그저 인간 테스터가 대상 앱에서 일련의 사용자 작업을 수행하도록 하는 것입니다. 그러면서 육안으로 jank가 있는지 살펴보든가, 아니면 오랜 시간을 들여 도구 중심적인 관점으로 jank를 찾아내는 것입니다. + + 하지만 이와 같은 수동식 방법은 위험 투성이입니다. 프레임 속도 변화를 인지하는 사람의 능력에는 개인차가 극명하고, 시간도 오래 걸릴 뿐더러 지루하고 오류가 발생할 가능성이 높습니다. + + +</p> + +<p> + 보다 효율적인 접근 방식은 자동화된 UI 테스트로부터 가져온 주요 성능 메트릭을 기록하고 분석하는 것입니다. + Android M 개발자 미리 보기에는 새로운 로깅 기능이 포함되어 있어 애플리케이션 애니메이션의 jank의 양과 심각도를 판별하기 쉽고, 이를 사용해 현재 성능을 판단하고 앞으로의 성능 목표를 추적하기 위해 철저한 프로세스를 구축할 수도 있습니다. + + + +</p> + +<p> + 이 글에서는 그러한 데이터를 사용하여 성능 테스트를 자동화하는 데 권장되는 방안을 찬찬히 알려드립니다. + +</p> + +<p> + 이것은 주로 두 가지 주요 작업으로 나뉘어 있습니다. 첫째로 무엇을 테스트할지, 어떻게 테스트할지를 확인합니다. 그런 다음 두 번째로 자동화된 테스트 환경을 설정하고 유지 관리하는 것입니다. + + +</p> + + +<h3 id="ui-tests">UI 테스트 설정</h3> + +<p> + 자동화된 테스트를 시작하기 전에 우선 몇 가지 수준 높은 결정을 내려야 합니다. 그래야 테스트 공간과 스스로에게 필요한 부분을 제대로 숙지할 수 있습니다. + +</p> + +<h4> + 테스트할 주요 애니메이션/흐름 알아내기 +</h4> + +<p> + 성능이 불량한 것이 사용자에게 가장 눈에 띄는 것은 애니메이션이 원활히 작동하지 않을 때라는 점을 명심하십시오. + 따라서, 테스트할 UI 작업 유형을 식별할 때에는 사용자가 가장 많이 접하게 되는 애니메이션이나 사용자 환경에 가장 중요한 것에 주안점을 두면 유용합니다. + + 예를 들어 다음은 이처럼 식별하는 데 유용하게 쓰일 수 있는 몇 가지 보편적인 시나리오입니다. +</p> + +<ul> + <li>기본 ListView 또는 RecyclerView를 스크롤링 + </li> + + <li>비동기 대기 주기 동안 표시되는 애니메이션 + </li> + + <li>비트맵 로딩/조작이 들어 있을 수 있는 모든 애니메이션 + </li> + + <li>알파 혼합이 포함된 애니메이션 + </li> + + <li>Canvas로 사용자 지정 보기 드로잉 + </li> +</ul> + +<p> + 팀 구성원인 엔지니어, 디자이너와 제품 관리자와 협력하여 이와 같이 테스트 대상 범위에 넣어야 하는 주요 제품 애니메이션의 우선 순위를 지정하십시오. + +</p> + +<h4> + 앞으로의 목표를 정의하고 그것을 추적하기 +</h4> + +<p> + 레벨이 높을 때에는 특정한 성능 목표를 알아내고 테스트 작성에 집중하며, 그에 관한 데이터를 수집하는 것이 매우 중요할 수 있습니다. + 예를 들면 다음과 같습니다. +</p> + +<ul> + <li>처음에만 UI 성능을 추적하여 좀 더 자세히 알아보기만 했으면 합니까? + </li> + + <li>앞으로 마주치게 될 성능 저하를 방지하고자 합니까? + </li> + + <li>지금은 매끄러운 프레임 비율이 약 90% 정도이지만 이번 사분기 내에 98%까지 올리고자 합니까? + </li> + + <li>지금 매끄러운 프레임이 약 98%이고 성능이 저하되지 않기를 바랍니까? + </li> + + <li>저사양 기기에서 성능을 개선하는 것이 목표입니까? + </li> +</ul> + +<p> + 이 모든 경우, 애플리케이션의 여러 버전에 걸쳐 성능을 나타내주는 사용 기록 추적을 수행하는 것이 좋습니다. + +</p> + +<h4> + 테스트할 기기 정하기 +</h4> + +<p> + 애플리케이션의 성능은 어느 기기에서 실행되는지에 따라 여러 가지로 달라집니다. 메모리 용량이 적고 GPU 파워가 딸리거나 CPU 칩 속도가 느린 기기도 있습니다. + 이는 즉 한 가지 하드웨어 세트에서는 잘 작동하는 애니메이션이 다른 곳에서는 그렇지 않을 수도 있다는 뜻입니다. 더 나쁜 경우로는 파이프라인의 서로 다른 부분에서 병목 현상이 일어나는 결과를 초래할 수도 있습니다. + + 따라서, 사용자가 볼 수도 있는 이러한 변형을 감안하기 위해 테스트를 실행할 기기를 여러 가지로 선택하는 것이 중요합니다. 최신 고사양 기기, 저사양 기기, 태블릿 등 양쪽 측면을 모두 고려하십시오. + + CPU 성능, RAM, 화면 밀도, 크기 등의 변형을 잘 살피십시오. + 고사양 기기를 통과하는 테스트가 저사양 기기에서는 실패할 수도 있습니다. + +</p> + +<h4> + UI 테스트의 기본 프레임워크 +</h4> + +<p> + <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>와 <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso</a> 등의 도구 스위트는 개발자의 애플리케이션을 통과하는 사용자의 동작을 자동화하는 데 도움이 되도록 구축된 것입니다. + + 이들은 단순한 프레임워크로, 사용자와 기기의 상호작용을 흉내 냅니다. + 이러한 프레임워크를 사용하려면, 사실상 개발자가 나름의 고유한 스크립트를 생성해야 합니다. 이는 일련의 사용자-동작을 통해 실행되고, 이를 기기 자체에서 재생합니다. + + +</p> + +<p> + 이렇게 자동화된 테스트를 여러 가지로 조합하여 <code>dumpsys gfxinfo</code>와 함께 사용하면 재현 가능한 시스템을 재빨리 만들어내 테스트를 실행하고 해당 조건 하에서 성능 정보를 측정할 수 있습니다. + + +</p> + + +<h3 id="automated-tests">자동화된 UI 테스트 설정</h3> + +<p> + UI 테스트를 실행할 수 있게 되고, 한 번의 테스트로부터 데이터를 수집할 파이프라인을 갖추게 되면 다음으로 중요한 단계는 해당 테스트를 여러 번, 여러 기기에 걸쳐 실행하고 그 결과 도출된 성능 데이터를 집계하여 개발 팀이 한층 더 상세하게 분석할 수 있게 해주는 프레임워크를 채택하는 것입니다. + + + +</p> + +<h4> + 테스트 자동화를 위한 프레임워크 +</h4> + +<p> + UI 테스트 프레임워크(예: <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>)는 대상 기기/에뮬레이터에서 직접 실행된다는 점에 주목할 만한 가치가 있습니다. + 반면 <em>dumpsys gfxinfo</em>에 의해 완료되는 성능 수집 정보는 호스트 머신이 구동하여 ADB를 통해 명령을 전송합니다. + 이러한 각각의 항목 자동화를 연결하는 데 도움을 주기 위해 <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">MonkeyRunner</a> 프레임워크가 개발되었습니다. 이것은 호스트 머신에서 실행되는 스크립팅 시스템으로, 일련의 연결된 기기에 명령을 발행하기도 하고 이들로부터 데이터를 수신할 수도 있습니다. + + + +</p> + +<p> + UI 성능 테스트를 제대로 자동화하기 위해 최소한의 수준으로 일련의 스크립트를 구축하는 경우, 다음과 같은 작업을 수행하기 위해 monkeyRunner를 활용할 수 있어야 합니다. + +</p> + +<ul> + <li>원하는 APK를 대상 기기(하나 이상일 수 있음) 또는 에뮬레이터에 로드하여 시작합니다. + </li> + + <li>UI Automator UI 테스트를 시작하고 실행되도록 허용하십시오. + </li> + + <li><em>dumpsys gfxinfo</em><em></em>를 통해 성능 정보를 수집합니다. + </li> + + <li>정보를 집계하고 이를 다시 유용한 방식으로 표시해 개발자에게 보여줍니다. + </li> +</ul> + + +<h3 id="triage">관측된 문제 심사 및 수정</h3> + +<p> + 문제의 패턴이나 성능 저하를 확인했으면, 다음 단계는 해결 방법을 알아내어 적용합니다. + 자동화된 테스트 프레임워크가 프레임에 대해 정확한 타이밍 분석을 유지하는 경우, 최근의 의심스러운 코드/레이아웃 변경 내용을 꼼꼼히 훑어보거나(성능 저하의 경우) 수동 조사로 전환했을 때 시스템의 어느 부분을 분석할지 범위를 좁히는 데 도움이 될 수 있습니다. + + + 수동 조사의 경우, <a href="{@docRoot}tools/help/systrace.html">systrace</a>부터 시작하는 것이 좋습니다. 이렇게 하면 렌더링 파이프라인의 모든 단계, 시스템에 있는 모든 스레드와 코어는 물론 개발자가 정의한 사용자 지정 이벤트 마커 일체에 대해 정확한 타이밍 정보를 나타내주기 때문입니다. + + +</p> + +<h4> + 임시 타이밍을 적절하게 프로파일링하기 +</h4> + +<p> + 렌더링 성능에서 타이밍을 가져와 이를 측정하는 데 수반되는 몇 가지 어려움을 알아두는 것이 중요합니다. + 이와 같은 숫자는 본래 결정적인 것이 아니고 시스템 상태, 이용 가능한 메모리 용량, 열 제한 및 개발자가 사는 지역에 태양 플레어가 마지막으로 영향을 미친 시점 등에 따라 변동폭이 큽니다. + + 요점은 같은 테스트를 두 번 실행하면서 서로 근사치이지만 완전히 똑같지는 않은, 약간 다른 숫자를 얻어내는 데 있습니다. + + +</p> + +<p> + 이런 식으로 데이터를 제대로 수집하고 프로파일링한다는 것은 같은 테스트를 여러 번 거듭 실행하면서 얻어지는 결과를 평균 또는 중간값(너무 복잡해지니 이것을 '배치(batch)'라고 부르기로 합시다)으로 누적한다는 것을 뜻합니다. 이렇게 하면 테스트 성과를 대략적으로 어림잡을 수 있으면서 정확한 타이밍은 없어도 됩니다. + + + +</p> + +<p> + 이러한 배치를 코드 변경 사이사이에 사용하여 그러한 변경 내용이 성능에 미치는 상대적인 영향을 알아볼 수도 있습니다. + 변경 전 배치의 평균 프레임 속도가 변경 후 배치에서보다 빠른 경우, 해당 변경에 대해 전반적으로 좋은 WRT 성능을 성취했다는 뜻입니다. + + +</p> + +<p> + 이는 즉 개발자가 수행하는 자동화된 UI 테스트는 모두 이 개념을 감안해야 한다는 뜻이기도 하고, 테스트 중에 일어나는 모든 변칙적인 부분 또한 감안해야 한다는 뜻입니다. + 예를 들어 애플리케이션 성능이 일종의 기기 문제(본인의 애플리케이션에서 기인한 것이 아님) 때문에 갑자기 뚝 떨어지는 경우라면 해당 배치를 다시 실행하여 조금 덜 혼란스러운 타이밍을 얻어야 할 수도 있습니다. + + + +</p> + +<p> + 그렇다면 측정값이 의의를 지니려면 테스트를 몇 번이나 수행하는 것이 좋습니까? 최소한 10번은 해야 합니다. 실행 횟수가 50이나 100처럼 커질수록 더욱 정확한 경과를 도출할 수 있습니다(물론, 이제는 정확도와 시간을 맞바꿔야 하는 셈입니다). + + +</p> |