일일 정산 마감 파이프라인

FxDart 승 async

요구사항

하루를 마감하세요. 카드 거래 10건(아래 코드)에서: failed 거래는 버리고, 나머지를 판매자별로 묶은 뒤, 각 판매자의 순합계를 구하세요(환불은 음수). 각 판매자의 정산 내역을 은행 게이트웨이에 게시하되 — 동시 진행 중인 게시는 최대 두 건, 결과는 판매자 순서대로 — 그런 다음 보고서를 출력하세요: 판매자별 한 줄, 지급/수금 구분(한 판매자는 환불이 결제액을 초과함), 총합계, 그리고 최대 동시 진행 건수 증명.

이것은 라이브러리 전체가 한 파이프라인에 담긴 예제입니다. 동기 준비 단계: rejectgroupBy → 그룹별 sumBysortBy. toAsync로 비동기 경계를 넘어, concurrent(2) 아래에서 게시합니다. 보고서는 partitionsumBy를 다시 사용합니다.

예상 출력
2026-07-27 close — 3 merchants, 2 postings at a time:
  BookNook: 3 txns, net $-6.01
  Cafe Luna: 4 txns, net $32.00
  GadgetHub: 2 txns, net $218.90
payouts: 2, collections due: 1
settled: $244.89
max postings in flight: 2

나란히 보기

네이티브 Dart

FxDart

차이가 나는 이유

이 작업의 각 절반은 더 작은 예제에서 이미 등장했습니다; 여기서 중요한 것은 그 둘이 만났을 때 무슨 일이 벌어지는가입니다. 네이티브 Dart는 package:collection(groupListsBy, sortedBy)으로 준비 단계를 충분히 잘 처리합니다 — 다만 그룹별 합계를 내는 것은 명시적 시드를 가진 fold 이고, 지급 구분은 where를 두 번 통과시키는 것입니다. 그런 다음 비동기 경계에 부딪히면 구조가 무너집니다: 제한된 게시는 워커 풀이 필요하고, 슬롯과 커서를 가진 별도의 이름 붙은 함수가 되어, 읽고 있던 파이프라인이 추적해야 하는 배관으로 바뀝니다. FxDart 버전은 원본 거래부터 게시된 정산 내역까지 끊김 없는 체인 하나입니다 — 열네 줄로, 정책(무엇이 유효한지, 어떻게 묶는지, 게이트웨이를 얼마나 세게 두드릴지)이 눈에 보이는 텍스트이고, 메커니즘은 라이브러리의 몫입니다.

벤치마크

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 38 µs
FxDart 35 µs

최대 메모리 무승부

네이티브 Dart 16.5 MB
FxDart 16.7 MB

N = 10,000

시간 FxDart 승

네이티브 Dart 4.21 ms
FxDart 2.97 ms

최대 메모리 네이티브 승

네이티브 Dart 23.1 MB
FxDart 24.4 MB

N = 100,000

시간 FxDart 승

네이티브 Dart 48.9 ms
FxDart 30.7 ms

최대 메모리 무승부

네이티브 Dart 56.6 MB
FxDart 58.2 MB

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