속도 제한이 있는 배치 임포트

FxDart 승 async

요구사항

가계부 거래 9건(아래 코드에 있음)을 세 건씩 배치로, 한 번에 한 호출씩만 받는 임포트 엔드포인트로 보내세요 — 엄격하게 순차적이며 절대 겹치지 않습니다. 각 배치가 끝날 때마다 배치 크기, 금액, 지금까지 임포트된 누적 합계를 기록하세요. 배치 요약을 순서대로 출력한 다음, 최대 동시 진행 카운터(반드시 1이어야 합니다)를 통해 속도 제한이 지켜졌음을 증명하세요.

FxDart에서는 정책 전체가 체인입니다: chunk(3)이 배치 크기를 정하고, concurrent(1)이 속도를 정하며, scan이 응답들을 거치며 누적 합계를 실어 나릅니다 (drop(1)은 scan의 초기값을 버립니다). 엔드포인트 자체는 delay로 지연을 시뮬레이션하고 sumBy로 배치 합계를 계산합니다.

예상 출력
importing 9 txns in batches of 3, one at a time:
  batch 1: 3 txns, $172.49 — running total $172.49
  batch 2: 3 txns, $403.65 — running total $576.14
  batch 3: 3 txns, $325.34 — running total $901.48
max batches in flight: 1

나란히 보기

네이티브 Dart

FxDart

차이가 나는 이유

공정하게 말하자면: 엄격하게 순차적인 임포트는 평범한 for 루프가 무리 없이 다루는 유일한 동시성 정책이며, 네이티브 버전도 읽기 좋습니다 — package:collectionslices가 배치 분할까지 해결해 줍니다. 다만 누적 합계는 이미 손으로 이어 나가는 가변 상태이고(n++ 옆에 running += amount), scan은 이를 선언적인 한 단계로 바꿔줍니다. 그리고 이 루프의 단순함은 막다른 길이기도 합니다: 엔드포인트가 언젠가 두 배치의 동시 진행을 허용하게 되면, FxDart 버전은 12로 바꾸기만 하면 되지만, 루프는 다른 비동기 예제에 나온 워커 풀로 변해야 합니다. 체인은 정책을 선언하고, 루프는 정책을 코드로 구현합니다.

벤치마크

Apple M1 Max, RAM 32 GB · Dart 3.12.2 (AOT 컴파일) · 2026-08-24

비동기 예제입니다. 대표 스케일이 1,000,000이 아니라 N = 100,000인 이유 — 원소 하나마다 양쪽 모두 이벤트 루프를 한 바퀴 돌아야 하므로, 실제 await 백만 번은 파이프라인이 아니라 Dart 이벤트 루프를 몇 분씩 재게 됩니다. 지연은 0으로 두고 예제의 동시성 제한은 그대로 유지합니다. 막대가 비교하는 것은 파이프라인 기계 장치 자체입니다.

N = 100

시간 무승부

네이티브 Dart 156 µs
FxDart 177 µs

최대 메모리 무승부

네이티브 Dart 16.5 MB
FxDart 16.8 MB

N = 10,000

시간 네이티브 승

네이티브 Dart 12.7 ms
FxDart 17.3 ms

최대 메모리 네이티브 승

네이티브 Dart 24.0 MB
FxDart 27.5 MB

N = 100,000

시간 네이티브 승

네이티브 Dart 131.0 ms
FxDart 157.7 ms

최대 메모리 무승부

네이티브 Dart 75.9 MB
FxDart 79.7 MB

막대는 사이드별로 새 프로세스에서 반복 측정한 중앙값입니다(작은 N은 타이머 해상도를 위해 배치 처리). 두 사이드가 서로 5% 이내이거나 — 사람이 지각할 수 없는 차이인 0.6ms 이내이면 — 무승부로 칩니다. 상대 차이가 근소한 경우는 최대 5회까지 다시 측정합니다. 앱에서는 어느 막대가 짧든 몇 밀리초 이하의 차이는 사용자에게 보이지 않습니다. 메모리는 프로세스 최대 RSS입니다. Dart VM과 데이터셋은 양쪽이 동일하므로, 두 막대의 차이가 곧 파이프라인 자체가 붙들고 있는 양입니다.