Fill gaps in a sparse time series
Requirement
Transactions for July 1–14 (data in the code) exist only on some days.
Build the dense daily series — days with no
transactions count as 0.00 — then print it as two weekly
rows, each with its 7 daily values and a week total. Both versions must
print the block under Expected output.
Expected output
Daily spend, July 1-14 (0.00 = no transactions) Jul 01-07: 16.70 0.00 30.00 0.00 0.00 8.75 0.00 | week total 55.45 Jul 08-14: 22.10 0.00 0.00 19.60 0.00 9.90 0.00 | week total 51.60
Side by side
Native Dart
FxDart
Why they differ
Gap-filling means driving the pipeline from the calendar, not
from the data: range(1, 15) generates every day,
groupBy answers "what happened that day", and
sumBy over a possibly-empty group yields the 0.00 for quiet
days for free. The weekly rollup is then chunk(7) +
zipWithIndex — reshaping the dense series without a single
index calculation beyond the row label. Native Dart gets the dense
series with a counting for and the rollup with
slices/indexed from
package:collection — workable, but the sum-of-a-group step
is a seeded fold both times, and the two phases don't
compose into one visible flow.
Benchmark
N = 100
Time Tie
Peak memory Tie
N = 10,000
Time Tie
Peak memory FxDart wins
N = 1,000,000
Time FxDart wins
Peak memory Native 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.