Energy Efficiency - 코드 작성 단계에서 에너지 효율을 높이는 방법

·

6 min read

모든 앱은 네트워킹 작업을 수행 할 때, 사용자 인터페이스를 업데이트 할 때, CPU에서 코드를 실행 할 때마다 에너지를 소비합니다. 사용자가 이용하는 앱들이 많아지면서 에너지 효율성을 끌어올리는 것은 사용자 경험에 필수적인 요소가 되었습니다.

사용자는 언제든지 아이폰의 [설정]-[배터리 항목]에 들어가서 앱별 배터리 사용량을 볼 수 있습니다. 아마 배터리 효율성이 매우 떨어지는 앱이라면 사용자는 그 앱을 지워버리고 싶어질지도 모릅니다.😱

앱의 사소한 비효율성이 모여 배터리 수명, 성능, 응답 속도등에 상당한 영향을 미칠 수 있습니다. 그래서 오늘은 에너지 효율성을 끌어올리기 위해 어떤 것들을 중점적으로 보아야 하는지와 코드 작성 단계에서 에너지 효율을 높이는 방법에 대해 알아보고자 합니다.

우선 에너지가 무엇인지 먼저 알아봅시다.


에너지란?

에너지는 전력 x 시간으로 시간의 흐름에 따라 얼마만큼의 전력을 사용했는지를 표현하는 개념입니다. 전력은 특정 시점에 필요한 에너지의 순간을 측정한 것으로, 에너지는 일정 기간(와트시W)동안 사용된 전력(줄J)을 측정 한 것입니다. 가용할 수 있는 에너지는 유한하기 때문에 효율을 끌어올리는 것이 중요합니다. 그리고 에너지는 배터리에 저장되며 더 많은 전력이 필요하면 시간이 지남에 따라 소멸됩니다.

에너지는 fixed cost와 dynamic cost로 분류 할 수 있습니다.

fixed cost

  • 앱이 작업을 수행하기 위해 시스템과 다양한 리소스를 가져와서 작업이 완료된 후 다시 내려가는 데 사용되는 에너지의 양

dynamic cost

  • 실제 어떤 작업을 수행하면서 앱에서 사용하는 에너지의 양

Overhead

  • 작업을 수행하기 위해 하드웨어를 가동하는 데 필요한 에너지 양

유휴 상태에서는 전력이 거의 소모되지 않고 에너지 영향도 적습니다. 그러나 작업이 활발히 진행되면 시스템 리소스가 사용되고 이러한 리소스에는 에너지가 필요하게 됩니다. 산발적인 작업으로 인해 기기가 아무 작업도 하지 않을 때는 유휴 상태나 활성 상태가 아닌 중간 상태가 될 수 있습니다.

중간 상태일 때는 다음 작업이 실행되기 전에 기기가 완전한 유휴 상태에 도달하는 데 충분한 시간이 없을 수 있습니다. 이 경우 에너지가 낭비되고 사용자의 배터리가 더 빨리 소모되게 됩니다. 산발적인 작업이 많이 발생하면 리소스가 산발적인 작업 사이에 완전한 유휴 상태에 도달 할 기회를 얻지 못할 수 있으므로 dynamic cost와 상당한 fixed cost가 발생하게 됩니다. 이 상황은 상대적으로 적은 양의 에너지를 필요로 하는 작업에 많은 에너지를 사용하게 합니다.

그럼 에너지를 소비하는 것에는 어떤 것들이 있는 지 알아봅시다.


에너지를 소모하는 것들

image.png 주로 Processing, Networking, Location, Graphics이 가장 큰 비중으로 에너지를 소모합니다. 앱을 만들 때 이 네가지 부분을 다룰 때면 조금 더 신경써야 할 부분들입니다. 오늘은 이 네가지 요소 중 Graphics와 Networking에 대해 조금 더 알아보고자 합니다.

Graphics

먼저 그래픽을 보겠습니다. Graphics는 정말 에너지 집약적인 작업입니다. 특히 앱에서 화면의 가려진 영역을 새로고침한다던지 애니메이션을 과도하게 사용하지 않는 편이 좋습니다.

앱이 화면에 콘텐츠를 업데이트 할 때마다 CPU, GPU 및 화면이 활성화되어야하는데요, 관련이 없거나 비효율적인 드로잉은 시스템 리소스를 저전력 상태에서 빼내거나 전원이 완전히 꺼지는 것을 방지하여 상당한 에너지 사용을 초래할 수 있습니다.

그래픽 작업 시 에너지 소모를 줄일 수 있는 방안들입니다.

그래픽 작업 시 에너지 소모를 줄이려면

1. 앱에서 사용하는 뷰의 숫자를 줄이기

2. 되도록 Blur 사용을 삼가기

자주 변경되는 부분이라면 블러를 사용하지 않는게 좋습니다. 콘텐츠가 변경 될 때마다 background와 블러가 들어간 반투명 뷰를 모두 업데이트해야하므로 에너지 비용이 증가하게 됩니다.

3. 화면 업데이트는 최소화하기

화면 업데이트가 사용자에게 필요한 변경사항을 제공하는 것인지 먼저 확인합니다. 그리고 화면 변화가 진짜 필요한 경우에만 업데이트 합니다. 화면이 가려지거나 짤리거나 꺼져있을 때는 화면 업데이트 작업을 하지 않는 것이 좋습니다. 애니메이션에 더 낮은 프레임 속도를 사용하고 꼭 사용자에게 필요한 경우에만 높은 프레임 속도를 사용하는 것이 좋습니다. 게임하는 게 아니라면 대체로 낮은 프레임 속도도 괜찮습니다.

4. 복잡한 UI 삼가기

UI의 복잡성에 따라 에너지 소비가 크게 좌우됩니다. 보기에 예쁘지만 의도하지 않은 사이드 이펙트를 발생시킬 여지가 있습니다.

5. 풀스크린 비디오 재생중에는 UI레이어 제한하기

iOS는 전체 화면 비디오를 재생하는 동안 리소스를 효율적으로 관리하여 에너지를 절약하도록 최적화되어 있습니다. 재생중인 동영상 위아래에 부가적인 UI 레이어는 GPU와 같은 추가 리소스를 늘려이 최적화를 저하시킬 수 있습니다. AVPlayerViewController 클래스에서 제공하는 표준 클래스와 동작들은 재생 중에 자동으로 숨겨집니다. 앱은 정당한 이유없이 전체 화면 비디오 위에 숨겨진 레이러를 포함해서 추가 레이어를 추가하지 않아야합니다. 사용자가 탭 등을 통해 요청할 때 전체 화면 비디오에 컨트롤 및 기타 UI 요소를 표시하는 것은 정상이며 예상되는 동작입니다. 그러나 사용자가 상호 작용하지 않을 때 제거해야합니다.


Networking

거의 모든 iOS 앱은 일종의 네트워크 작업을 수행하는데, 네트워크 작업을 수행할때마다 상당한 오버헤드 비용이 발생합니다. 그래서 가능한 오버헤드를 줄이고 효율적으로 네트워킹을 사용하는 것이 중요합니다.

셀룰러나 Wi-Fi 같은 네트워킹 하드웨어는 배터리를 절약하기 위해 기본적으로 전원이 꺼집니다. 네트워킹을 하려면 이러한 리소스의 전원을 켜야합니다. 그런 다음 활동 기간 동안 그리고 더 많은 작업을 예상하여 바로 유휴상태에 들어가지 않고 일정 기간 동안 유지됩니다. 그래서 산발적인 네트워크 트랜잭션은 높은 오버 헤드를 초래하고 기기의 배터리를 빠르게 고갈시킬 수 있습니다.

네트워킹 작업 시 에너지에 영향을 주는 요인들은 다음과 같습니다.

  1. 셀룰러는 Wi-Fi에 비해 많은 에너지를 필요로 합니다.
  2. 네트워크 신호 조건이 안 좋을 때는 다시 시도해야 하므로 더 많은 에너지를 소모합니다.
  3. 지리적인 위치, 셀룰러 제공 업체에 따라 에너지 소모량이 달라질 수 있습니다.

이러한 외부적인 요인 외에 코드로 네트워킹을 최소화 해 에너지를 절약할 수 있는 방법들이 있는데요, 몇가지 지침을 준수하면 네트워킹을 최소화 할 수 있습니다. 네트워크 트랜잭션(네트워킹 단위)은 오버 헤드를 줄이기 위해 가능한 한 작아야합니다.

네트워킹 작업 시 에너지 소모를 줄이려면

1. 데이터 사이즈를 줄입니다.

첫 번째로는 이미지, 영상 등의 미디어들의 품질, 사이즈를 줄이는 방법입니다. 품질과 사이즈를 줄이게 되면 송수신되는 데이터의 양이 줄어들게 됩니다. 가장 작은 크기가 가장 에너지 효율적입니다.

두 번째로는 데이터를 압축하는 방법입니다. 데이터를 보내거나 받기 전 가능한 많이 압축해서 전달하면 에너지 소모량이 줄어들게 됩니다.

2. 중복된 네트워킹 요청을 줄입니다.

앱이 동일한 데이터를 반복적으로 다운로드 하지 않게 합니다.

  • 데이터 캐시 : 자주 업데이트 되지 않는 데이터를 로컬에 캐시합니다. 데이터 변경 / 사용자 요청의 경우에만 다시 다운로드 하는 방법입니다.

  • 일시정지 / 재개 : 네트워크 상태가 변동하고 신호 손실이 정기적으로 발생할 수 있습니다. 중단 된 작업을 재개 할 수 있도록 준비해 동일한 콘텐츠가 여러 번 다운로드되지 않도록 합니다. 경우에 따라서는 사용자가 다운로드를 일시 중지하고 나중에 다시 시작하도록하는 것이 합리적인데요, 예를 들어 iOS에서는 사용자가 부분적으로 다운로드 된 앱 아이콘을 탭하여 앱 다운로드를 일시 중지 할 수 있습니다. URLSessionresume, pause 메서드를 이용할 수 있습니다.

3. 에러 핸들링

  • 네트워크 상태 확인 네트워크 작업이 실패하면 SCNetworkReachability API를 사용하여 현재 연결된 네트워크가 사용가능한지 확인합니다. 문제가 있는 경우 호스트를 다시 사용할 수있을 때까지 사용자에게 경고하거나 작업을 연기합니다. wifi나 셀룰러 연결 등의 네트워크 상태를 체크하고 신호 컨디션을 확인해서 네트워킹이 가능한 상황에만 트랜잭션이 발생하도록 합니다.

  • Timeout 서버의 응답이 일정 시간동안 오지 않으면 더이상 기다리지 않도록 시간 제한을 설정해 불필요하게 네트워킹 연결을 열어두지 않도록 합니다. 30초에서 1분정도가 적당하며 네트워크 환경이 안좋은 상황일 수도 있으므로 너무 긴 시간 시도하지 않도록 합니다.

4. 네트워킹 작업 연기

네트워크 작업을 수행하는 앱은 네트워크 작업을 일괄 처리하고 적절한 API를 사용하여 무선 네트워크 사용을 최소화해야 합니다. 그래야 시스템 리소스에 대한 오버헤드를 줄여서 에너지 효율성을 높일 수 있습니다. 컨텐츠를 한번에 조금씩 다운로드하면 네트워크를 연결하는 시스템의 전원이 계속 켜져서 전력이 낭비됩니다. 예를 들어 비디오 스트리밍 시 전체(혹은 많은 부분)을 한번에 다운로드 하거나 광고를 제공하거나 메시지 다운로드시 일괄처리 하는 것이 에너지 효율에 유리합니다.

NSURLSession은 HTTP를 통한 업로드, 다운로드 작업의 경우 지연 가능한 백그라운드 세션을 생성하는 기능(URLSesstionConfiguration.BackgroundSession)을 제공합니다. 이 백그라운드 세션을 사용하면 앱이 URL 요청을 시스템에 보내어 최적의 시간에 요청을 수행하고 완료되면 앱에 알립니다.

네트워크 작업에 이 방법을 사용하면 몇 가지 이점이 있습니다.

  1. Background Session을 이용하면 미래에 발생할 다른 네트워킹과 이벤트가 통합되어서 추가로 소모되는 오버헤드를 줄일 수 있습니다.
  2. 전송이 발생하는 시기를 시스템이 제어합니다.
  3. Background Session을 이용하면 적절한 시간에 업로드/다운로드 작업이 시스템에 의해 이뤄지도록 할 수 있습니다.
  4. 자동적으로 재시도하므로 재시도 정책을 다루는데 신경쓰지 않아도 됩니다.
  5. 처리량 모니터링(throughtput monitoring)도 제공하는데 네트워크 상태등이 좋지않아서 처리량이 매우 낮은 경우 작업이 중지되고 나중에 성공할 것이라고 생각되는 시점에 다시 시도합니다.
  6. 작업하다 오류 발생시 시스템에서 URL세션을 자동으로 재시도합니다.

참고로 사용자가 백그라운드 세션을 시작한 앱을 강제 종료하는 경우는 백그라운드 활동도 취소됩니다.


지금까지 앱에서 에너지를 많이 소모하는 부분은 무엇인지와 코드를 통해 에너지 효율을 개선하는 방법에 대해 알아보았습니다. 오늘 다루지 못한 Location, Processing에 대해서는 다음번에 알아보겠습니다.


References