Plate 63
Decimal vs float Sum: Localhost Lab
Hands-on Decimal vs float cumulative sum lab: real ops/s plus a simple accuracy note (not financial advice), measured on Linux localhost (lab) for SREs.
Aditya Challa4 min read
Intro — what this post promises
Should a hot cumulative sum use float or decimal.Decimal? This lab reports ops/s for summing many 0.1-style addends on Linux localhost, plus a simple accuracy note (exact Decimal vs binary float drift). Not financial, tax, or accounting advice.
Related links:
- statistics vs manual mean localhost lab
- json dumps compact vs indent localhost lab
- pickle vs json roundtrip localhost lab
- threading local vs dict localhost lab
- asyncio gather vs taskgroup localhost lab
- hashlib md5 vs blake2b localhost lab
- csv reader vs split localhost lab
- counter vs dict tally localhost lab
Lab honesty (1 Oct 2026 IST): Python 3.13.5, decimal precision 28. Affiliates: 0. No Docker. Values built from Decimal("0.1") / float 0.1.
Verdict up front (n=1 000 000 loop): float ~43.01 Mops/s vs Decimal ~17.18 Mops/s (~2.5×). Float loop sum of 0.1 drifted by ~1.333e-06 from exact 100000; Decimal matched exact. Builtin sum(float) ~110.42 Mops/s and printed exact 100000.0 here (compensated summation) — still not a substitute for decimal money types.
Arms
| Arm | Pattern |
|---|---|
| float loop | s = 0.0; s += 0.1 × n |
float sum() | sum(list_of_floats) |
| Decimal loop | s = Decimal("0"); s += Decimal("0.1") |
Decimal sum() | sum(decs, Decimal("0")) |
| mixed 0.1/0.01 | same for both types |
Lab topology
Script: lab-evidence/85-decimal-vs-float-sum/results/run_lab.py.
Lead table — n=1 000 000 (p50)
| Arm | Mops/s | Result snippet |
|---|---|---|
| float loop | 43.01 | 100000.00000133288 |
| float sum() | 110.42 | 100000.0 |
| Decimal loop | 17.18 | 100000.0 |
| Decimal sum() | 19.91 | 100000.0 |
Speed across n
| n | float loop | Decimal loop | float÷Decimal |
|---|---|---|---|
| 10 000 | 61.58 | 17.52 | 3.52× |
| 100 000 | 61.03 | 17.01 | 3.59× |
| 1 000 000 | 43.01 | 17.18 | 2.5× |
Accuracy note (not advice)
| n | exact (Decimal) | float loop abs error | Decimal matches? |
|---|---|---|---|
| 10 000 | 1000.0 | 1.588205e-10 | True |
| 1 000 000 | 100000.0 | 1.332883e-06 | True |
0.1 is not exact in binary float, so a naive loop accumulates visible error as n grows (~1.6e-10 → ~1.3e-6 here). Decimal("0.1") summed exactly at this precision. Python’s builtin sum() on floats used a more accurate algorithm on this run and printed the clean integer-valued total — great for analytics, still not a decimal money type.
Reading it
- Float wins speed (~2.5× on the 1 M loop); Decimal wins exact base-10 addends.
- Use float for scientific/telemetry sums where relative error is acceptable.
- Use Decimal (or integer cents) when base-10 exactness matters more than Mops/s.
- Do not treat this as ledger/tax guidance — pick types with your domain rules and tests.
float sum() vs float loop
On 3.13, sum(list_of_floats) was both faster (~110.42 vs ~43.01 Mops/s) and more accurate for this 0.1×n case than a handwritten loop. Prefer sum/math.fsum over naive loops when you stay in binary float — and still switch to Decimal/integers when exact decimal fractions are a requirement.
Integer cents alternative
For currency-like totals, many teams store integer minor units (cents) and only format on output — fast like int add, exact like Decimal for two-place money. This lab did not bench int cents; it is the usual escape hatch when Decimal Mops/s hurt and float error is unacceptable.
Pitfalls
- Constructing
Decimal(0.1)from a float (imports binary error) — useDecimal("0.1"). - Comparing stringified floats to Decimals carelessly.
- Assuming “
sum()was exact once” means money is safe in float. - Ignoring precision context (
getcontext().prec) for huge Decimal workloads.
Reproduce
Evidence: summary.json, summary.txt.
Limits
One Linux box. Default Decimal precision 28. Not mpmath/numpy. Not banking standards (IEEE 754-decimal, currency rounding modes).
Takeaway
Float loop ~43.01 Mops/s vs Decimal ~17.18 Mops/s (~2.5×) at n=1 M, but the float loop was ~1.333e-06 off exact 0.1×n while Decimal matched. Speed is float; exact tenths are Decimal (or integer cents). Choose deliberately.
Lab evidence
What I found running this
Lab 1 Oct 2026 IST. Python 3.13.5. n=1e6: float_loop 43.01 Mops/s vs Decimal_loop 17.18 (~2.5x); float_sum 110.42; float_loop abs err ~1.333e-06; Decimal exact match. Not financial advice. Affiliates: 0. Evidence: lab-evidence/85-decimal-vs-float-sum/.
Related links
Plate 12
islice vs list Slice Windows: Localhost Lab
Hands-on itertools.islice vs list slice window lab: real ops/s taking ranges from sequences, measured on Linux localhost in this hands-on lab for SREs.
Observability & SRE · 1 Oct 2026
Plate 71
html.escape vs Manual Replace: Localhost Lab
A hands-on localhost lab comparing html.escape with chained str.replace for safe HTML escaping.
Observability & SRE · 30 Sept 2026
Plate 17
difflib vs set Ops Similarity: Localhost Lab
Hands-on difflib.SequenceMatcher vs set Jaccard token similarity: real ops/s on token lists, measured on Linux localhost in this hands-on lab for SREs.
Observability & SRE · 30 Sept 2026