Unique visitors, first visit kept
Requirement
Today's visit log holds eight visits by four accounts. Keep each user's first visit only — deduping across the whole log, not just adjacent entries — and print who they are, when they first arrived, and the unique count. The data is in the code; both versions must print the lines shown under Expected output.
Expected output
ana — first visit 09:02 ben — first visit 09:15 cho — first visit 10:05 dee — first visit 11:01 4 unique visitors in 8 visits
Side by side
RxDart
FxDart
Why they differ
This is one of RxDart's best matches for an FxDart operator.
Plain Stream.distinct only compares adjacent
events (FxDart's uniqAdjacent is the same idea), so
RxDart adds distinctUnique: dedup across the whole
stream, first occurrence kept — exactly uniqBy's
contract. Both maintain a seen-set for the stream's lifetime, both
preserve arrival order, and ana's 09:40 and 11:48 revisits vanish
identically on both sides.
The remaining difference is ergonomic, not semantic. "Same visitor"
is one key function for uniqBy —
(v) => v.user — while distinctUnique
asks for a matched equals + hashCode pair,
two closures that must agree with each other. That is a mild
inconvenience, not a model gap, and the async main is the usual
stream overhead on fixed data. Verdict: a tie — the global-dedup operator exists on
both sides and behaves the same way.
Benchmark
N = 100
Time Tie
Peak memory Tie
N = 1,000,000
Time FxDart wins
Peak memory Tie
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.