Inventory restock plan

FxDart wins

Requirement

From a stock list (data in the code), find items below their minimum stock, prioritize by biggest deficit, and order them in that priority order — but stop before the cumulative cost exceeds the $500 budget. Print each planned order with its running total, then a summary of what was ordered and what is left. Both versions must print the plan under Expected output.

Expected output
Restock plan (budget $500.00)
  Paper Cups      x200  $10.00   running $10.00
  Espresso Beans  x 12  $216.00  running $226.00
  Oat Milk        x 24  $91.20   running $317.20
  Filter Papers   x 10  $64.00   running $381.20
  Cleaning Tabs   x  8  $76.00   running $457.20
Ordering 5 of 6 needed items; total $457.20, $42.80 left

Side by side

Native Dart

FxDart

Why they differ

The budget cutoff is the interesting part. FxDart turns the running total into data: scan produces the cumulative cost stream, zip pairs each item with its running total, and takeWhile cuts the plan at the budget — the cutoff rule is one predicate on one line, and the running totals are already there to print. Native Dart interleaves everything in a single loop: a mutable running variable, an early break, and formatting all share the loop body, so the policy ("stop when over budget") lives inside control flow instead of being a visible pipeline stage you could move or test on its own.

Benchmark

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

N = 100

Time Tie

Native Dart 11 µs
FxDart 6.7 µs

Peak memory Tie

Native Dart 16.6 MB
FxDart 16.5 MB

N = 10,000

Time FxDart wins

Native Dart 1.30 ms
FxDart 312 µs

Peak memory Native wins

Native Dart 17.5 MB
FxDart 23.4 MB

N = 1,000,000

Time FxDart wins

Native Dart 216.2 ms
FxDart 51.9 ms

Peak memory Native wins

Native Dart 174.0 MB
FxDart 193.1 MB

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.