Weekly totals from a daily series
Requirement
Three weeks of daily spend (August 1–21, stored in cents) roll up
into one line per week: week n: $total, with the total
converted to dollars at two decimal places. The 21 amounts are in the
code; both versions must print the three lines shown under
Expected output.
Expected output
week 1: $83.50 week 2: $89.95 week 3: $91.75
Side by side
RxDart
FxDart
Why they differ
The windowing itself is a wash: bufferCount(7) and
chunk(7) are the identical idiom for the same fixed window,
and both would emit a short trailing window if 21 didn't divide
evenly. The job splits on numbering the windows. RxDart has
no indexed operator, so the idiomatic move is to draft
scan as a counter — an accumulator record whose only
role is to carry week + 1 alongside the buffer. It
works, but the fold is a bystander wearing a state operator's
clothes.
The pull side has a purpose-built word: zipWithIndex
pairs each chunk with its position lazily, no accumulator in sight,
and sumBy folds each week's cents into dollars in the
same breath. That is the recurring tier-2 pattern — both models
window finite data fine, but the pull vocabulary is wider exactly
where bookkeeping (indexes, keys, partial aggregates) meets the
window. One repurposed operator versus one intended one: the verdict
goes to FxDart.
Benchmark
N = 98
Time Tie
Peak memory Tie
N = 999,999
Time FxDart wins
Peak memory RxDart wins
Bars are medians of repeated timed iterations in fresh processes per side (small N is batched for timer resolution). Sides within 5% of each other — or within 0.6 ms, a difference no person can perceive — count as a tie; close relative races are re-measured up to 5 runs. In an app, anything under a few milliseconds is invisible to the user regardless of which bar is shorter. Memory is peak process RSS. The Dart VM and the dataset are identical on both sides, so the difference between the two bars is what the pipeline itself holds onto.