본문 바로가기
다트(Dart) 언어 강좌

스트림과 Iterable 을 알아보자

by everythingdev 2024. 7. 29.
반응형

스트림과 Iterable - 데이터 처리의 핵심을 알아보자.

  • 플러터를 시작하기 전 다트(Dart) 언어의 개념에 대해 정리를 해보고자 합니다.
  • 다트(Dart) 언어 개념 정리 포스팅 후 플러터(Flutter) 개념 정리로 넘어갈 예정입니다.
  • 플러터(Flutter) 개념 정리 후 실습이 시작 된다고 보시면 될 것 같습니다.

소개

  • Dart 프로그래밍 언어는 현대적이고 효율적인 애플리케이션 개발을 위한 강력한 도구를 제공합니다.
  • 그 중에서도 스트림(Stream)과 Iterable은 데이터 처리와 관련된 핵심적인 개념입니다.
  • 이번 포스팅에서는 Dart의 스트림과 Iterable에 대해 자세히 알아보고, 이들을 효과적으로 활용하는 방법을 살펴보겠습니다.

스트림(Stream)이란?

스트림은 비동기적으로 데이터 시퀀스를 처리하는 방법을 제공합니다. 실시간으로 발생하는 이벤트, 대용량 파일 읽기, 네트워크 요청 등 시간에 따라 변화하는 데이터를 다룰 때 유용합니다.

스트림의 주요 특징

  1. 비동기 처리 : 스트림은 데이터가 준비되는 대로 처리할 수 있어, 애플리케이션의 반응성을 높입니다.
  2. 연속적인 데이터 흐름 : 데이터가 연속적으로 발생하는 상황에 적합합니다.
  3. 에러 처리 : 스트림은 데이터 처리 중 발생할 수 있는 오류를 효과적으로 관리합니다.
  4. 변환과 필터링 : 스트림의 데이터를 쉽게 변환하거나 필터링할 수 있습니다.

스트림 사용 예시

Stream<int> countStream(int max) async* {
  for (int i = 1; i <= max; i++) {
    yield i;
    await Future.delayed(Duration(seconds: 1));
  }
}

void main() async {
  var stream = countStream(5);
  await for (var number in stream) {
    print(number);
  }
}

  • 이 예시에서는 1부터 5까지의 숫자를 1초 간격으로 출력하는 스트림을 생성하고 사용합니다.

Iterable이란?

Iterable은 순차적으로 접근 가능한 데이터 컬렉션을 나타냅니다. 리스트, 셋, 맵의 키 등이 Iterable의 예입니다.

Iterable의 주요 특징

  1. 순차적 접근 : 요소들을 하나씩 순차적으로 접근할 수 있습니다.
  2. 지연 평가 : 필요한 시점에 요소를 평가하여 메모리를 효율적으로 사용합니다.
  3. 다양한 연산 : map, where, reduce 등 다양한 고차 함수를 지원합니다.
  4. 반복 가능 : for-in 루프 등에서 사용할 수 있습니다.

Iterable 사용 예시

void main() {
  var numbers = [1, 2, 3, 4, 5];
  var doubledNumbers = numbers.map((n) => n * 2);

  for (var number in doubledNumbers) {
    print(number);
  }
}
  • 이 예시에서는 리스트의 각 요소를 2배로 만드는 새로운 Iterable을 생성하고 출력합니다.

스트림과 Iterable의 차이점

스트림과 Iterable은 모두 데이터 시퀀스를 다루지만, 몇 가지 중요한 차이점이 있습니다:

  1. 동기 vs 비동기 : Iterable은 동기적으로 동작하는 반면, 스트림은 비동기적으로 동작합니다.
  2. 데이터 가용성 : Iterable의 모든 데이터는 즉시 사용 가능하지만, 스트림의 데이터는 시간에 따라 사용 가능해집니다.
  3. 메모리 사용 : Iterable은 모든 데이터를 메모리에 유지할 수 있지만, 스트림은 필요한 데이터만 메모리에 유지합니다.
  4. 재사용성 : Iterable은 여러 번 반복할 수 있지만, 스트림은 일반적으로 한 번만 사용할 수 있습니다.

스트림과 Iterable의 활용

스트림 활용

  1. 이벤트 처리 : 사용자 입력, 센서 데이터 등의 실시간 이벤트 처리에 적합합니다.
  2. 파일 처리 : 대용량 파일을 효율적으로 읽고 처리할 수 있습니다.
  3. 네트워크 통신 : 웹소켓 등을 통한 실시간 데이터 수신에 유용합니다.
Stream<String> readFile(String path) async* {
  final file = File(path);
  Stream<String> lines = file.openRead()
    .transform(utf8.decoder)
    .transform(LineSplitter());
  await for (var line in lines) {
    yield line;
  }
}

Iterable 활용

  1. 데이터 변환 : map, where 등을 사용하여 데이터를 쉽게 변환할 수 있습니다.
  2. 데이터 필터링 : 조건에 맞는 요소만 선택할 수 있습니다.
  3. 데이터 집계 : reduce, fold 등을 사용하여 데이터를 집계할 수 있습니다.
void main() {
  var numbers = [1, 2, 3, 4, 5];
  var sum = numbers.reduce((value, element) => value + element);
  print('Sum: $sum');

  var evenNumbers = numbers.where((number) => number % 2 == 0);
  print('Even numbers: $evenNumbers');
}

성능 고려사항

스트림과 Iterable을 사용할 때는 성능을 고려해야 합니다:

  1. 메모리 사용 : 대량의 데이터를 다룰 때는 스트림을 사용하여 메모리 사용을 최적화할 수 있습니다.
  2. 지연 평가 : Iterable의 지연 평가를 활용하여 불필요한 연산을 줄일 수 있습니다.
  3. 비동기 처리 : 스트림을 사용하여 장시간 실행되는 작업을 비동기적으로 처리하면 애플리케이션의 반응성을 향상시킬 수 있습니다.

결론

  • Dart의 스트림과 Iterable은 데이터 처리를 위한 강력하고 유연한 도구입니다. 스트림은 비동기적이고 연속적인 데이터 흐름을 처리하는 데 적합하며, Iterable은 동기적이고 유한한 데이터 컬렉션을 다루는 데 유용합니다. 두 개념을 적절히 활용하면 효율적이고 유지보수가 용이한 코드를 작성할 수 있습니다.
  • 개발자는 각 상황에 맞는 적절한 도구를 선택하여 사용해야 합니다. 실시간 데이터나 대용량 데이터를 처리할 때는 스트림을, 메모리에 올라와 있는 유한한 데이터 컬렉션을 다룰 때는 Iterable을 사용하는 것이 좋습니다. 이러한 개념을 잘 이해하고 활용한다면, Dart를 사용한 애플리케이션 개발에서 더욱 효과적인 데이터 처리가 가능할 것입니다.

맺음말

  • 이번 포스팅에서는 다트의 스트림과 iterable에 대해 알아보았습니다.
  • 다음 포스팅에서는 다트의 파일 입출력에 대해 알아보고자 합니다.
반응형