Flutter Logs는 얼마나 견고한가?

CLI로 flutter logs를 실행하면 flutter에서 print 명령으로 전달된 로그를 확인할 수 있습니다. 이건 너무 간단한 일인데, 사용하다보니 과연 끊김없이 잘 전달 될까 하는 고민이 들더라구요. 그래서 실험을 해봤습니다. 지난번에 메모리 체크를 위해 만들었던 HelloWord 앱을 조금 바꿔서 테스트를 해봤어요.

_timer = Timer.periodic(Duration(seconds: 10), (timer) {
    if (_counter < 2880) {
      setState(() {
        _counter++;
      });
      print("MyLog: ${_counter}");
    }
  });

10초에 한번씩 2880번, 그러니까 8시간동안 계속 로그를 남겨봤습니다.

flutter logs > mylog.log

PC에서는 이렇게 실행해놓고

앱을 킨 다음에 와이파이 켜놓고 8시간동안 잠을 자면 실험 끝인데요.

다음날 일어나서 로그파일을 확인하니, 2880번 실행된게 아니군요. 1770번 까지만 실행되어 있었습니다. 중간에 앱이 꺼져있기도 했고, PC의 절전모드를 끄는걸 깜빡했습니다. 뭐.. 아무튼 1770번 로그가 전달되는 동안 빠트림 없이 왔느냐를 체크해봅면 됩니다. 그런데 뭔가 이상하네요.

이미지1

1770개가 있어야 하는데 1771개가 존재한다고 나옵니다. 뭔가 중복된게 아닌지 의심됩니다. 거참 귀찮게 하는구먼~

스크립트를 짤까 하다가 자세히보니 오! 찾았다 요놈!! 중간에 26이 두번 왔네요.

  • 타이머가 2번 발생할리는 없겠죠?
  • 그렇다면 패킷이 두번 왔다는건가? 근데 그것도 타이머가 2번 발생할 확률만큼 낮지 않을까요?
  • print가 2번 데이터를 보냈다는게 합리적인 추론인데, 이게 print 자체의 문제인지 값을 받아들이는 flutter logs의 문제인지는 더 연구가 필요할 듯 합니다.

결론

상황에 따라서 flutter logs가 중복된 log를 받을 수 있으니 유의합시다

Dart 언어 관련 기초적인 정리

다른 언어도 마찬가지지만 아주 기본적인 개념이지만 쉽게 까먹거나 정리를 잘 안하고 넘어가는 것들이 있습니다.

이런것들을 한번 개념정리 해봅시다.

dynamic vs var

var a = 1;
a = "Hello"; // ERROR
dynamic b = 1;
b = "Hello"; // OK
  • var : 불분명한 타입이지만 한번 선언된 타입을 바꾸면 안됩니다.
  • dynamic : 타입을 바꿀 수 있습니다.

JavaScript의 변수와 비슷한건 dynamic이라고 할 수 있겠네요. 추측건데 저장비용이나 연산비용은 후자가 더 많을 것 같습니다.

final vs const vs static

먼저 final 과 const의 차이점을 알아봅시다. 간단하죠~

const int a = 1; // OK
const int b = getOne(); // ERROR
final int c = 2; // OK
final int d = getTwo(); // OK
  • 공통점 : 둘다 처음에 결정된 값을 바꾸지 못합니다.
  • 차이점 : const는 컴파일 전에 값을 결정, final은 런타임시에 값을 결정해도 됩니다.

당연히 이것도 저장비용, 연산비용에 차이점에 있으니까 고대부터 다르게 존재해 왔겠죠?

그럼 static은 무엇이냐?

class Aclass {
  static int B = 1;
  get getB => B;
  int addB() => B++;
}

void main() {
  var a1 = Aclass();
  var a2 = Aclass();
  a2.addB();
  print(a1.getB);
  print(a2.getB);
  print(Aclass.B);
  print(Aclass.getB); // ERROR
}
  • static 으로 선언하면 해당 클래스로 선언된 모든 오브젝트에 공통으로 적용됩니다.
  • 심지어 클래스명 자체로 접근도 가능하죠.
  • 일종의 같은 클래스끼리의 전역변수로 사용할 수 있습니다.

Future vs Stream

  • Future는 JavaScript에서 async/await를 생각하면 됩니다. 실행이 완료될 때 까지 기다립니다.
  • Stream은 yield를 이용해서 특정 변수를 리턴함으로써, 중간과정에서 이벤트를 발생시킵니다.
  • Flutter에서 시간에 따른 UI 변화를 줘야 할 때 두 기능을 이용한 FutureBuilder, StreamBuilder를 사용하게 됩니다. 이때 용도도 그 정의에 따라서 달라집니다.
    • FutureBuilder : 뭔가 값이 완성될 때 까지 뺑뺑이를 돌리다가 값이 완성되면 UI 표출 할 때 사용
    • StreamBuilder : 초시계처럼 특정순간 마다 값이 바뀔때 사용

Flutter VS Native 메모리 사용량 비교

지난번 포스팅에서 Flutter DevTools을 이용하면서 제가 만든 앱의 메모리 사용량이 너무 과도하다는 점을 확인했었습니다. 별거 아닌 테스트용 앱인데도 카카오톡의 사용량을 능가하는게 너무 이상했었죠.

IntelliJ Idea에서 Flutter App 성능 프로파일링 하기

그래서 오늘은 프로젝트를 막 생성했을 때. 즉 초기상태의 Hello World 앱만 가지고 Flutter와 Native 앱의 메모리 사용량 비교를 해보았습니다. 다 읽는데 5분도 안걸려요~

먼저 Flutter 입니다. 이런 앱이에요. 만들면 바로 나오는거…

이미지1

160MB나 할당되어 있네요. 인스타그램이 300인데.. 지까지것이 뭐라고… ㄷㄷㄷ

이미지1

이번에는 Native 앱입니다. 이런 앱입니다. 생김새는 다르지만 하는일은 크게 다르지 않은 초기상태의 Hello World 앱이에요.

이미지1

보이시나요? hello_world_flutter와 hello_word_native(?) 의 메모리 차이가~ 앱 이름에 ‘l’자 하나 안들어갔다고 3배 차이가 나고 있네요. (아이고 이놈의 오타)

이미지1

여기저기서 아티클을 검색해서 보니까 어쩔수 없는 차이가 있는것 같네요. 아무래도 flutter로 계속 개발하려면 메모리 최적화에 신경 안쓸수가 없을것 같아요. 할당되는 메모리양(RSS) 줄이는것도 방법이 있다면 찾아보려고 합니다. 방법이 있다면 공유하도록 하겠습니다.