Dart vs FxDart

같은 실전 과제를 두 번 풉니다: 왼쪽은 순수 Dart, 오른쪽은 FxDart입니다. 두 버전 모두 브라우저에서 바로 실행되며 정확히 같은 결과를 출력합니다 — 직접 비교하고 판단해 보세요.

목록을 보기 전에 한 가지는 정직하게 짚고 넘어가겠습니다: Dart의 내장 Iterable은 이미 지연 평가되며, 단순한 where/map 체인은 그 자체로 훌륭한 Dart 코드입니다. FxDart는 이런 코드를 이기려고 있는 게 아닙니다. FxDart가 더하는 것은 어휘 (groupBy, chunk, zip, scan, uniqBy, partition — 기본 Dart로는 직접 손으로 구현해야 하는 것들입니다), 조합(중첩 호출과 중간 변수 대신 타입이 있는 fx() 체인 하나로 표현하기), 그리고 무엇보다 동시성 제어입니다 — .concurrent(n)는 비동기 파이프라인을 한 번에 n개씩, 순서를 유지하며 실행합니다. 이는 순수 Dart로는 수작업 워커 풀로만 근접하게 흉내 낼 수 있는 부분입니다. 각 예제에는 판정 배지가 붙어 있고, 그중 일부는 네이티브 Dart로도 충분하다고 말합니다. 바로 그 점이 핵심입니다: 어떤 예제가 정말로 FxDart가 낫다고 말할 때는, 그 말을 믿을 수 있습니다.

FxDart 승 — 이 경우는 명확히 더 낫습니다 · 우열 없음 — 둘 다 좋아서 취향껏 고르면 됩니다 · 네이티브로 충분 — 순수 Dart로도 잘 처리됩니다 · async — 비동기 파이프라인을 사용합니다

예제마다 두 가지 관점을 보여줍니다. 채워진 배지는 코드에 대한 판정 — 어느 쪽이 더 쓰고 읽기 좋은가입니다. 테두리만 있는 ⚡ 배지는 측정 결과 — 가장 큰 벤치마크 크기에서 AOT 컴파일로 실측한 실행 시간 승자이며, 전체 그래프는 각 페이지의 벤치마크 섹션에 있습니다.

다섯 개만 본다면, 이 예제들을 보세요: #1 가장 큰 지출 상위 3건 · #11 총지출 기준 상위 5개 판매자 · #23 상위 판매자를 동시에 보강하기 · #31 다중 통화 지출 리포트 · #53 두 스냅숏 사이의 가격 하락

1부 · 함수 2개

일상적인 한 줄 코드입니다. 여기서는 네이티브 Dart도 곧잘 따라옵니다 — 판정 배지를 눈여겨보세요.

  1. 1 가장 큰 지출 상위 3건 우열 없음 ⚡ FxDart가 더 빠름 이번 달 거래 중 금액이 가장 큰 세 건 — package:collection의 sortedBy + take와 FxDart의 sortBy + take를 비교합니다.
  2. 2 가장 많이 발생한 로그 레벨 FxDart 승 ⚡ FxDart가 더 빠름 로그 항목을 레벨별로 세어 가장 많은 것을 고릅니다 — 순수 Dart의 groupListsBy + reduce와 FxDart의 countBy + maxBy를 비교합니다.
  3. 3 원격 설정 세 개를 순서대로 불러오기 FxDart 승 async ⚡ 속도 동일 순차 비동기 fetch — 순수 Dart의 평범한 await-in-loop 대 FxDart의 toAsync + map, 단어 하나 차이로 동시성 제한 버전이 됩니다.
  4. 4 100달러 초과 주문의 평균값 우열 없음 ⚡ FxDart가 더 빠름 고액 주문의 평균 총액을 구합니다 — package:collection을 사용한 where/map/average와 FxDart의 filter + averageBy를 비교합니다.
  5. 5 사용자를 10명씩 페이지로 나누기 FxDart 승 ⚡ FxDart가 더 빠름 사용자 목록을 고정 크기 페이지로 나눕니다 — package:collection의 slices와 FxDart의 chunk + map을 비교합니다.
  6. 6 리더보드 순위 라벨 우열 없음 ⚡ 속도 동일 정렬된 리더보드에 1부터 n까지 번호를 매깁니다 — Dart 3의 indexed 레코드와 FxDart의 zipWithIndex + map을 비교합니다.
  7. 7 계좌 잔액 추이 FxDart 승 ⚡ 네이티브가 더 빠름 매 거래 후의 잔액 — 순수 Dart의 가변 누산 루프 대 FxDart의 scan + map.
  8. 8 이번 달 식비 합계 FxDart 승 ⚡ FxDart가 더 빠름 가계부 한 카테고리를 합산합니다 — 순수 Dart의 where/fold 체인과 FxDart의 filter + sumBy를 비교합니다.
  9. 9 첫 방문 순서로 보는 판매자 목록 FxDart 승 ⚡ 네이티브가 더 빠름 순서를 유지하는 중복 제거 — 순수 Dart의 seen-set 루프와 FxDart의 map + uniq를 비교합니다.
  10. 10 한계를 처음 넘긴 센서 측정값 네이티브로 충분 ⚡ 속도 동일 기준값을 넘는 첫 온도를 찾습니다 — 순수 Dart의 skipWhile + firstOrNull과 FxDart의 dropWhile + head를 비교합니다.

2부 · 함수 3개

네이티브 Dart에는 없는 어휘가 빛을 발하기 시작합니다: groupBy, uniqBy, partition, scan.

  1. 11 총지출 기준 상위 5개 판매자 FxDart 승 ⚡ FxDart가 더 빠름 가계부를 판매자별로 그룹화해 합계 순위를 매깁니다 — 순수 Dart의 groupListsBy + sortedBy와 FxDart의 groupedBy → sortByDesc → take 체인 하나를 비교합니다.
  2. 12 모든 게시물의 태그를 정렬해 모으기 우열 없음 ⚡ FxDart가 더 빠름 게시물 태그를 하나의 정렬된 중복 없는 리스트로 평탄화합니다 — 순수 Dart의 expand + toSet + sort와 FxDart의 flatMap + uniq + sort를 비교합니다. 코드는 무승부, 시계는 1.5배 차이입니다.
  3. 13 환불과 청구, 둘 다 포맷팅 FxDart 승 ⚡ FxDart가 더 빠름 원장을 환불과 청구로 나누어 두 쪽 모두 출력합니다 — 순수 Dart의 where 두 번 대 FxDart의 partition 한 번을 비교합니다.
  4. 14 정규화한 유효 이메일 상위 5개 네이티브로 충분 ⚡ FxDart가 더 빠름 다듬고, 소문자로 바꾸고, 유효성을 검사한 뒤 다섯 개를 취합니다 — 순수 Dart의 map/where/take와 FxDart의 map + filter + take를 비교합니다. 이 경우 순수 Dart도 똑같이 깔끔합니다.
  5. 15 두 개씩 프로필 가져오기 FxDart 승 async ⚡ 네이티브가 더 빠름 순서를 지키는 동시성 제한 — 순수 Dart로 직접 만든 워커 풀과 FxDart의 toAsync + map + concurrent를 비교합니다.
  6. 16 복리 이자 테이블 FxDart 승 ⚡ 네이티브가 더 빠름 연 5%의 연도별 잔액 테이블입니다 — 순수 Dart의 가변 누산 루프와 FxDart의 range + scan + map을 비교합니다.
  7. 17 거래당 평균 지출이 가장 높은 카테고리 FxDart 승 ⚡ 네이티브가 더 빠름 지출을 그룹화해 거래당 가장 비싼 카테고리를 찾습니다 — 순수 Dart에서 collection의 groupBy + maxBy 중첩 호출과 하나의 FxDart 체인을 비교합니다.
  8. 18 특정 기간 안의 지출 우열 없음 ⚡ FxDart가 더 빠름 날짜순으로 정렬된 가계부의 한 구간을 합산합니다 — 순수 Dart의 skipWhile/takeWhile/fold와 FxDart의 dropWhile + takeWhile + sumBy를 비교합니다. 네이티브 쪽도 충분히 잘 버팁니다.
  9. 19 센서와 측정값 짝짓고 이상치 찾기 FxDart 승 ⚡ 네이티브가 더 빠름 두 개의 병렬 리스트를 결합해 고온 측정값에 표시합니다 — 순수 Dart의 인덱스 루프(core에는 zip이 없음) 대 FxDart의 zip + filter + map.
  10. 20 최근 오류 메시지, 중복 제거 FxDart 승 ⚡ 네이티브가 더 빠름 최신순 로그에서 가장 최근의 서로 다른 오류 3개를 추출합니다 — 순수 Dart의 seen-Set 루프와 break 대 FxDart의 filter + uniqBy + take를 비교합니다.

3부 · 함수 5개

실제 리포트와 파이프라인입니다 — 여러 단계로 이루어진 로직을 조합으로 읽기 쉽게 유지합니다.

  1. 21 중복 거래 찾아내기 FxDart 승 ⚡ 속도 동일 판매자, 금액, 날짜가 같은 청구를 표시합니다 — 순수 Dart의 putIfAbsent와 중첩 루프를 FxDart의 groupBy + filter + flatMap과 비교합니다.
  2. 22 지출 없는 날의 최장 연속 기록 FxDart 승 ⚡ 속도 동일 지출이 전혀 없었던 7월 날짜의 최장 연속 구간을 찾습니다 — 순수 Dart의 streak/longest 카운터 루프와 FxDart의 range + scan + max를 비교합니다.
  3. 23 상위 판매자를 동시에 보강하기 FxDart 승 async ⚡ 네이티브가 더 빠름 상위 3개 판매자를 고른 뒤, 요청 속도 제한이 있는 API로 두 개씩 조회합니다 — 순수 Dart로 직접 만든 워커 풀과 FxDart의 concurrent(2)를 비교합니다.
  4. 24 동점 순위가 있는 리더보드 FxDart 승 ⚡ FxDart가 더 빠름 동점 점수가 같은 순위를 공유하도록 선수 순위를 매깁니다 — 순수 Dart의 가변 rank/prevScore 상태와 FxDart의 sortBy + groupBy + zipWithIndex를 비교합니다.
  5. 25 일별 측정값으로 구하는 주간 평균 FxDart 승 ⚡ 속도 동일 21개의 일별 측정값을 3개의 주간 평균으로 접습니다 — 순수 Dart의 인덱스 연산과 sublist, FxDart의 chunk + averageBy + zipWithIndex를 비교합니다.
  6. 26 페이지네이션된 상품 목록 우열 없음 ⚡ 네이티브가 더 빠름 필터링하고 가격순으로 정렬한 뒤 2페이지를 잘라냅니다 — Dart에는 이미 skip/take가 있으므로 이번에는 진짜 무승부입니다.
  7. 27 라인 항목에서 청구서 요약까지 FxDart 승 ⚡ FxDart가 더 빠름 주문의 라인 항목을 카테고리별 합계와 총합으로 만듭니다 — 순수 Dart의 루프와 fold라는 두 관용구를 FxDart의 groupBy + sumBy + sortBy와 비교합니다.
  8. 28 월 예산을 초과한 카테고리 FxDart 승 ⚡ FxDart가 더 빠름 카테고리별 지출을 합산하고, 예산을 초과한 것만 남긴 뒤, 초과액 순으로 정렬합니다 — 순수 Dart의 가변 맵 기반 집계와 FxDart의 groupBy + filter + sortBy를 비교합니다.
  9. 29 지출액순으로 정렬한 월간 카테고리 리포트 FxDart 승 ⚡ 네이티브가 더 빠름 가계부를 한 달로 필터링하고 카테고리별로 합산해 순위를 매깁니다 — 순수 Dart의 루프와 가변 맵을 FxDart의 filter + groupBy + sortBy와 비교합니다.
  10. 30 한계를 세 번 연속 초과한 측정값 FxDart 승 ⚡ 네이티브가 더 빠름 CO2 측정값이 세 시간 연속으로 1000 ppm을 넘는 구간을 모두 찾습니다 — 순수 Dart의 인덱스 루프와 FxDart의 zip3 + drop으로 만든 슬라이딩 윈도우를 비교합니다.

4부 · 함수 6~10개

대부분 동시성 제한이 걸린 전체 워크플로입니다 — 네이티브 Dart로는 깔끔하게 표현할 수 없는 영역입니다.

  1. 31 다중 통화 지출 리포트 FxDart 승 ⚡ FxDart가 더 빠름 고정 환율로 여행 가계부를 USD로 정규화한 다음 그룹화, 순위화, 요약합니다 — 리포트 줄마다 파이프라인 하나 쓰는 방식과 fold/reduce 보일러플레이트를 비교합니다.
  2. 32 재고 재주문 계획 FxDart 승 ⚡ FxDart가 더 빠름 기준치 미달 품목의 우선순위를 정하고 예산선에서 주문 목록을 잘라냅니다 — 데이터 흐름으로서의 scan + zip + takeWhile 대 가변 누적 합계와 break.
  3. 33 폴백이 있는 동시 가격 조회 FxDart 승 async ⚡ 속도 동일 실시간 가격을 한 번에 세 개씩 조회하고, 누락된 SKU는 카탈로그 가격으로 대체합니다 — concurrent + null 병합 map과 워커 풀을 비교합니다.
  4. 34 전체 월간 가계부 리포트 FxDart 승 ⚡ FxDart가 더 빠름 가계부로부터 하나의 리포트 문자열을 만듭니다 — 총액, 카테고리별 내역, 상위 판매자를 세 개의 fxdart 파이프라인과 루프 및 중간 맵으로 각각 비교합니다.
  5. 35 희소한 시계열의 빈틈 채우기 FxDart 승 ⚡ FxDart가 더 빠름 거래가 없는 날은 0.00이 되고, 이어서 합계가 있는 주간 행이 만들어집니다 — 하나의 흐름으로서의 range + groupBy + chunk 대 카운팅 루프와 슬라이스.
  6. 36 병렬 다운로드, 순서대로 결과 받기 FxDart 승 async ⚡ 네이티브가 더 빠름 속도가 제각각인 다운로드 여섯 개를 한 번에 세 개씩 — concurrent는 완료 순서가 뒤섞여도 요청 순서를 유지하지만, 네이티브는 풀 관리가 필요합니다.
  7. 37 두 가계부 스냅샷 비교 FxDart 승 ⚡ 네이티브가 더 빠름 두 스냅샷 사이의 추가/삭제/불변 항목을 찾습니다 — id 기준 differenceBy와 intersectionBy를 직접 만든 id 집합과 where 필터 조합과 비교합니다.
  8. 38 불안정한 API를 첫 성공까지 폴링하기 FxDart 승 async ⚡ 네이티브가 더 빠름 준비될 때까지의 재시도를 지연 파이프라인으로 표현합니다 — range + toAsync + map + dropWhile + head와 break를 쓰는 명령형 폴링 루프를 비교합니다.
  9. 39 서비스와 심각도별 로그 알림 다이제스트 FxDart 승 ⚡ 속도 동일 WARN과 ERROR 로그를 들여쓰기된 다이제스트로 표현합니다 — groupBy + flatMap + uniq를 이용한 중첩 그룹화와 세 겹의 중첩 루프 및 seen 집합을 비교합니다.
  10. 40 엔드포인트별 p50/p95 지연 시간 FxDart 승 ⚡ 속도 동일 원본 요청 로그로부터 백분위수 표를 만듭니다 — 엔드포인트별 groupBy + sortBy + nth와 제자리 정렬을 쓰는 행 누적 루프를 비교합니다.
  11. 41 두 페이징된 피드를 이어붙이고 중복 제거하기 FxDart 승 async ⚡ 네이티브가 더 빠름 기본 로그 저장소를 먼저 소진한 뒤 복제본을 읽고, id로 중복을 제거하며 8개에서 멈춥니다 — concat + uniqBy + take는 지연 상태를 유지하지만, 네이티브는 seen 집합을 쓰는 중첩 루프가 필요합니다.
  12. 42 주변 맥락과 함께 보는 이상치 FxDart 승 ⚡ FxDart가 더 빠름 한계를 초과한 센서 측정값을 앞뒤 한 줄씩과 함께 보여줍니다 — zipWithIndex + flatMap + uniq로 이루어진 하나의 파이프라인과 중첩 루프로 만든 인덱스 집합을 비교합니다.
  13. 43 평활화된 구간 전환 FxDart 승 ⚡ FxDart가 더 빠름 이동 평균, 구간 런, 전환 알림 — 순수 Dart의 가변 상태를 든 인덱스 루프 세 개 vs FxDart의 windowed → uniqAdjacentBy → pairwise 체인.
  14. 44 센서 스트림에서 윈도우 단위 경고 감지하기 FxDart 승 async ⚡ 네이티브가 더 빠름 실제 Dart Stream을 고정 크기 윈도우로 나누어 경고를 발생시킵니다 — fromStream + chunk + averageBy와 await-for에서의 수동 버퍼 관리를 비교합니다.
  15. 45 키 입력 스트림 위의 실시간 검색 FxDart 승 async ⚡ 네이티브가 더 빠름 키 입력 스트림을 중복 제거된 백엔드 검색으로 바꿉니다 — fromStream + filter + uniq + take + map과 guard 절이 있는 await-for를 비교합니다.
  16. 46 속도 제한이 있는 배치 임포트 FxDart 승 async ⚡ 네이티브가 더 빠름 거래 9건을 3건씩 배치로, 한 번에 한 배치씩 임포트하며 누적 합계를 계산합니다 — chunk + concurrent(1) + scan과 순차 루프를 비교합니다.
  17. 47 이번 달 카테고리 순위 FxDart 승 ⚡ 속도 동일 지출을 그룹핑·합산·순위 매기기 — 순수 Dart의 groupListsBy와 비교자 뒤집기 vs FxDart의 groupedBy → sortByDesc 체인 하나.
  18. 48 재고 재평가, 조회는 한 번에 셋 FxDart 승 async ⚡ 네이티브가 더 빠름 대체 가격이 있는 실시간 가격 조회 — 순수 Dart의 워커 풀과 손수 만든 쌍 vs FxDart의 attach + concurrent + countWhere.
  19. 49 프로필 10개를 세 개씩 가져오기 FxDart 승 async ⚡ 속도 동일 동기 준비 과정이 그대로 제한된 동시성으로 이어집니다 — filter와 sort 다음에 toAsync + map + concurrent(3)를 잇는 방식과 직접 만든 워커 풀을 비교합니다.
  20. 50 코호트 리텐션 테이블 FxDart 승 ⚡ 속도 동일 가입월 기준 코호트와 이후 활동을 비교합니다 — 중첩된 groupBy/dropWhile/filter 파이프라인과 누산 리스트를 사용하는 중첩 for 루프를 비교합니다.
  21. 51 피날레 — DailyLedger 월말 마감 FxDart 승 async ⚡ 속도 동일 마지막 예제입니다: 가계부 항목을 세 개씩 불러온 뒤 7월 요약과 카테고리 분석을 계산합니다 — 실제 DailyLedger 앱에서 쓰는 형태를 두 방식으로 비교합니다.
  22. 52 일일 정산 마감 파이프라인 FxDart 승 async ⚡ FxDart가 더 빠름 검증하고, 판매자별로 묶고, 2건씩 게시한 다음 보고합니다 — 동기에서 비동기로 넘어가는 체인 하나 대 groupListsBy와 워커 풀.
  23. 53 두 스냅숏 사이의 가격 하락 FxDart 승 ⚡ FxDart가 더 빠름 두 가격표 스냅숏을 비교해 저렴해진 항목을 보고합니다 — indexBy + filter + sortBy + head + sumBy와, 맵 리터럴 및 where/fold 체인을 비교합니다.