한계를 세 번 연속 초과한 측정값

FxDart 승

요구사항

하루치 시간별 CO2 측정값이 주어집니다. 세 시간 연속으로 1000 ppm을 넘는 모든 구간을 찾아내세요 — 이는 환기 장치가 세 시간 내내 따라잡지 못했다는 뜻입니다 — 그리고 각 구간을 헤더 줄 아래에 시작–종료 시각 범위로 출력하세요. 데이터는 아래 코드에 있으며, 두 버전 모두 예상 출력 아래에 표시된 줄을 출력해야 합니다.

예상 출력
Ventilation alerts (3h over 1000 ppm):
11:00–13:00
15:00–17:00

나란히 보기

네이티브 Dart

FxDart

차이가 나는 이유

순수 Dart 코어에는 슬라이딩 윈도우가 없으므로, 네이티브 버전은 i + 2 < length 경계와 세 번의 수동 조회를 가진 인덱스 루프가 됩니다 — 맞기는 하지만, 그 안의 모든 조각이 읽는 사람이 직접 확인해야 하는 부기 작업입니다. FxDart 버전은 윈도우 자체를 데이터로 만듭니다: 리스트를 자기 자신과 하나씩, 둘씩 밀어서(drop(1), drop(2)) zip3하면, 각 원소가 (현재값, 다음값, 다다음값) 삼중항이 됩니다 — 인덱스는 어디에도 없습니다. zip3이 가장 짧은 입력에서 멈추는 성질이 바로 루프가 경계 조건으로 인코딩했던 "윈도우가 완전히 들어맞아야 한다"는 규칙 그 자체입니다. 윈도우를 4시간으로 넓히는 일은 밀어 넣는 입력을 하나 더 추가하는 것일 뿐, 산술식을 다시 검토할 필요가 없습니다.

밀어 넣은 입력들은 복사본이 아닙니다. List에 대한 drop(n)은 그 리스트의 구간이고, zip3은 세 구간을 모두 인덱스로 읽습니다 — 그래서 이 파이프라인은 측정값을 한 번만 훑고 윈도우당 삼중항 하나만 할당합니다. 막대그래프가 루프의 몇 배가 아니라 루프에 가깝게 붙어 있는 이유가 이것입니다.

벤치마크

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

N = 100

시간 무승부

네이티브 Dart 2.1 µs
FxDart 2.4 µs

최대 메모리 무승부

네이티브 Dart 16.4 MB
FxDart 16.5 MB

N = 10,000

시간 무승부

네이티브 Dart 114 µs
FxDart 173 µs

최대 메모리 네이티브 승

네이티브 Dart 20.5 MB
FxDart 23.5 MB

N = 1,000,000

시간 네이티브 승

네이티브 Dart 17.1 ms
FxDart 20.3 ms

최대 메모리 무승부

네이티브 Dart 149.8 MB
FxDart 148.0 MB

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