상위 판매자를 동시에 보강하기
요구사항
7월의 판매자별 지출 합계에서 상위 3개 판매자를 골라, (가상의) 판매자 디렉터리 API로 각각의 카테고리를 조회해 보강하세요 — 다만 이 API는 요청 속도를 제한하므로, 동시에 진행 중인 조회가 두 개를 넘지 않아야 합니다. 모든 조회가 끝난 뒤 결과를 지출 순서대로 출력하며, 가짜 조회 함수는 겹쳐서 실행된 요청 수를 세어 두 버전 모두 제한이 지켜졌음을 증명합니다. 데이터는 아래 코드에 있으며, 두 버전 모두 예상 출력 아래에 표시된 줄을 출력해야 합니다.
예상 출력
Green Grocer — $118.65 (Groceries) Electric Co — $60.34 (Utilities) Noodle Bar — $54.70 (Dining) max lookups in flight: 2
나란히 보기
네이티브 Dart
FxDart
차이가 나는 이유
이 작업은 중간에 성격이 바뀝니다 — 동기적인 순위 매기기에서 속도
제한이 있는 I/O로 — 그런데 코드의 성격도 함께 바뀌는 쪽은
한 버전뿐입니다. FxDart에서는 그 경계가 체인의 한 단계일 뿐입니다:
sortBy + take가 판매자를 고르고,
toAsync가 비동기로 넘어가며, map +
concurrent(2)가 조회를 순서대로 두 개씩 실행합니다.
네이티브 Dart에는 "최대 두 개까지만 동시에"를 표현할 기본 도구가
없습니다: Future.wait는 전부 한꺼번에 실행해 버리므로,
제한이 걸린 절반은 직접 만든 워커 풀 — 공유 커서, 미리 크기를 정한
결과 슬롯, 워커 퓨처 — 이 되어, 정작 그것이 뒷받침하는 두 줄짜리 순위
매기기를 압도해버립니다. 제한값을 바꾸거나 아예 없애는 일은 체인에서는
숫자 하나지만, 저 워커 풀 전체에서는 그렇지 않습니다.
벤치마크
비동기 예제입니다. 대표 스케일이 1,000,000이 아니라 N = 100,000인 이유 — 원소 하나마다 양쪽 모두 이벤트 루프를 한 바퀴 돌아야 하므로, 실제 await 백만 번은 파이프라인이 아니라 Dart 이벤트 루프를 몇 분씩 재게 됩니다. 지연은 0으로 두고 예제의 동시성 제한은 그대로 유지합니다. 막대가 비교하는 것은 파이프라인 기계 장치 자체입니다.
N = 100
시간 무승부
최대 메모리 무승부
N = 10,000
시간 네이티브 승
최대 메모리 무승부
N = 100,000
시간 네이티브 승
최대 메모리 무승부
막대는 사이드별로 새 프로세스에서 반복 측정한 중앙값입니다(작은 N은 타이머 해상도를 위해 배치 처리). 두 사이드가 서로 5% 이내이거나 — 사람이 지각할 수 없는 차이인 0.6ms 이내이면 — 무승부로 칩니다. 상대 차이가 근소한 경우는 최대 5회까지 다시 측정합니다. 앱에서는 어느 막대가 짧든 몇 밀리초 이하의 차이는 사용자에게 보이지 않습니다. 메모리는 프로세스 최대 RSS입니다. Dart VM과 데이터셋은 양쪽이 동일하므로, 두 막대의 차이가 곧 파이프라인 자체가 붙들고 있는 양입니다.