Dartの勉強11−3:同期・非同期(ジェネレーター:Generator)
ジェネレーターは、大量の繰り返し処理等で以下の特徴があります。
- sync* は同期ジェネレーター関数を、async*は非同期ジェネレーター関数を示します。
- yield キーワードを使って値を1つずつ返します。
- すべての値を一度に計算しないため、大きなデータセットでも効率的です。
ジェネレーターには同期ジェネレーターと非同期ジェネレーターがあります。
- 同期ジェネレーター
リストやセットなどの繰り返し可能なコレクションIterableを生成します。Iterable<int> syncGenerator(int n) sync* { for (int i = 0; i < n; i++) { yield i; // 値を1つずつ返す } } void main() { var nums = syncGenerator(5); // 0から4までの値を生成 for (var num in nums) { print(num); // 0, 1, 2, 3, 4 を順に表示 } } - 非同期ジェネレーター
非同期処理を伴う値のストリームを生成します。Stream<int> asyncGenerator(int n) async* { for (int i = 0; i < n; i++) { await Future.delayed(Duration(seconds: 1)); // 1秒待つ yield i; // 値を1つずつ返す } } void main() async { var nums = asyncGenerator(5); // 0から4までの値を1秒ごとに生成 await for (var num in nums) { print(num); // 1秒ごとに 0, 1, 2, 3, 4 を順に表示 } }センサーからのデータ取得やネットワークからのリアルタイムデータ取得など、非同期のシナリオで便利です。
- 先生によるまとめ
ジェネレーターが大量の画像処理で役立つ理由
(1) 遅延評価(lazy evaluation):
• すべての画像を一度にメモリに読み込むのではなく、必要なタイミングで1つずつ読み込み・処理できます。
• メモリを効率的に使えるため、大量のデータを扱う際のパフォーマンスが向上します。
(2) ストリーム処理:
• ジェネレーターは次の画像を生成するまで待機するので、リアルタイム処理が可能です。
• たとえば、画像を1つずつ処理してアップロードしながら、次の画像を処理できます。
(3) 大規模データセットのスケーラビリティ:
• 1万枚、10万枚といった膨大な画像でも、ジェネレーターを使えば効率よく処理できます。