ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 51

  1. Blog
  2. /Observability & SRE

itertools vs Python loops Lab

Hands-on itertools vs pure Python loops lab: chain, islice, and accumulate vs equivalent for-loops with real ops/s, measured on Linux localhost (lab).

Aditya Challa·30 September 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — elements/s (p50)
  5. Reading it
  6. Pitfalls
  7. When to pick what
  8. Reproduce
  9. Closing

Intro — what this post promises

Is itertools “always faster” than a for loop? This lab compares chain, islice, and accumulate to equivalent pure-Python loops on N=500,000 ints on Linux localhost — plus the anti-pattern of concatenating lists first.

Related links:

  • copy vs deepcopy localhost lab
  • lru_cache hit vs miss localhost lab
  • python re vs str methods localhost lab
  • string concat vs join localhost lab
  • set vs list membership localhost lab
  • json vs orjson vs msgpack localhost lab
  • struct pack vs to_bytes localhost lab
  • sorted vs heapq vs bisect localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Work is summing/+= over range — not I/O. Affiliates: 0. ops/s = elements consumed ÷ p50 wall.

Verdict up front: chain ≈ two loops (0.95×). Materializing list(a)+list(b) is the loser (~1.99× slower than chain). islice beats enumerate+break (1.83×), but range(K) is still fastest if you can skip the parent iterator. accumulate ≈ manual running sum; bare sum(range) is the throughput king when you only need the total.


Arms

ArmWhat it does
chain_itertoolsfor x in chain(a, b)
chain_two_loopstwo sequential for loops
chain_list_concatfor x in list(a)+list(b)
islice_itertoolsislice(range(N), K) K=N/10
islice_enumerate_breakenumerate + break at K
islice_range_Kfor x in range(K)
accumulate_itertoolslast value of accumulate
accumulate_manualrunning total += x
sum_builtin_rangesum(range(N))

Lab topology

N = 500000; K = 50000 for islice arms
5 repeats, p50 wall → ops/s (elements/s)

Script: lab-evidence/55-itertools-vs-python-loops/results/run_lab.py.


Lead table — elements/s (p50)

Armops/sns/elemp50 ms
sum(range)125,741,6568.03.98
islice range(K)46,648,62321.41.07
islice itertools40,525,56824.71.23
chain two loops38,539,96425.912.97
accumulate itertools36,714,15927.213.62
chain itertools36,568,99727.313.67
accumulate manual34,747,71628.814.39
islice enumerate+break22,167,14945.12.26
list+list concat18,351,92754.527.25

Reading it

  • chain is about clarity, not a free speedup vs two loops (~peer). It does beat building one big list first.
  • islice wins when the source is a long iterator you cannot rewrite as range(K). The enumerate+break tax is real (~1.8×).
  • accumulate vs manual is a wash (~1.06×). Prefer it for API/composition; don’t expect magic.
  • sum() is in another class (~126M/s) — use it when you only need the aggregate.

Pitfalls

  1. Materializing then iterating — list(a)+list(b) doubled the time here.
  2. islice when range(K) works — skip the wrapper.
  3. Assuming C itertools always wins — tight Python loops on range are already fast.
  4. Comparing to sum unfairly — different result shape (scalar vs sequence of prefixes).

When to pick what

NeedPrefer
Concatenate iterators lazilyitertools.chain
First K of a streamislice (or slice/range if possible)
Running totals as a sequenceaccumulate
Just the totalsum / C-level reduce
Clarity in app codeitertools — measured cost is small

Reproduce

python3 lab-evidence/55-itertools-vs-python-loops/results/run_lab.py

Evidence: /workspace/lab-evidence/55-itertools-vs-python-loops/results/.


Closing

itertools is not automatically faster — it is often as fast, and safer than materializing. On this box chain ≈ two loops; list concat is ~0.5× slower. islice is ~1.8× enumerate+break. accumulate ≈ manual; sum(range) is ~126M/s when you only need the total. Choose for laziness and API — measure if the loop is hot.

itertoolschainisliceaccumulatepython loopslocalhost labsreiterator

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5; N=500000. chain itertools 36.6M vs two loops 38.5M (~0.95x); list+list concat 18.4M. islice 40.5M vs enumerate+break 22.2M (~1.83x). accumulate ~1.06x manual; sum() 126M. Affiliates: 0. Evidence: lab-evidence/55-itertools-vs-python-loops/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 40

    itertools.batched vs Manual Chunking: Localhost Lab

    Hands-on itertools.batched vs manual list-slice chunking: real items/s batching sequences, measured on Linux localhost today in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

  • 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 07

    heapq.merge vs sorted(chain): Localhost Lab

    Hands-on heapq.merge vs sorted(chain) multi-way merge: real records/s on pre-sorted lists, measured on Linux localhost today in this hands-on lab for SREs.

    Observability & SRE · 1 Oct 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — elements/s (p50)
  5. Reading it
  6. Pitfalls
  7. When to pick what
  8. Reproduce
  9. Closing
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove