ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 23

  1. Blog
  2. /Observability & SRE

textwrap.fill vs Manual Wrap: 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 — wraps/s (p50)
  5. Reading it
  6. What textwrap buys
  7. Fixture note
  8. When manual pack is enough
  9. fill vs wrap in practice
  10. Throughput vs features
  11. Pitfalls
  12. Reproduce
  13. Limits
  14. Takeaway

Intro — what this post promises

Wrapping a long paragraph to a fixed width: textwrap.fill, textwrap.wrap + join, a manual word-pack, or a hard character chunk. This lab reports wraps/s on generated fixtures (width 72) on Linux localhost.

Related links:

  • str translate vs replace localhost lab
  • csv reader vs split localhost lab
  • secrets vs urandom localhost lab
  • bytesio vs spooled tempfile localhost lab
  • json dumps compact vs indent localhost lab
  • decimal vs float sum localhost lab
  • weakref vs dict cache localhost lab
  • glob vs rglob vs walk localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Fixtures under lab-evidence/89-textwrap-fill-vs-manual/results/fixture_*.txt. Affiliates: 0. No Docker.

Verdict up front (1000 words): manual word-pack ~9632 wraps/s vs textwrap.fill ~1240 (~7.77×); hard chunk ~147102 but breaks mid-word. fill and manual agreed on 88 lines for this fixture.


Arms

ArmPattern
textwrap.fillstdlib paragraph fill
textwrap.wrap + joinsame engine, list then join
manual word-packaccumulate words until width
hard chunkslice every width chars (breaks words)

Lab topology

fixtures: 200 / 1000 / 5000 words · width=72 · 9 rounds · p50
metric: wraps/s = 1 / p50_s (full paragraph)

Script: lab-evidence/89-textwrap-fill-vs-manual/results/run_lab.py.


Lead table — wraps/s (p50)

Fixturefillwrap+joinmanual packhard chunk
200 words6071603443508509423
1000 words124012859632147102
5000 words252260192932842

Line counts (fill vs manual): 200→18/18; 1000→88/88; 5000→440/440.


Reading it

  • Manual word-pack ~7.77× faster than textwrap.fill on the 1000-word fixture — fill does more (expand tabs, sentence handling options, robustness).
  • fill ≈ wrap+join — pick fill for a string; wrap when you want a list of lines.
  • Hard chunk is not wrapping — it is the fastest and the wrong product for prose.
  • Prefer textwrap in application code unless profiling shows wrap in a hot loop; then a tight word-pack may be enough if you accept fewer features.

What textwrap buys

textwrap handles edge cases this manual pack skips: replace_whitespace, drop_whitespace, break_long_words, break_on_hyphens, max_lines / placeholder, and indent variants (fill/indent/shorten). Throughput is not the only scoreboard.


Fixture note

Paragraphs are synthetic word streams (no punctuation). That favors simple packers and keeps fill/manual line counts aligned here. Real prose with long URLs/hyphens can diverge — re-bench on your corpus.


When manual pack is enough

CLI help text, log pretty-printers, and offline report generators often need “width 72, break on spaces” and nothing else. A 20-line word-pack then wins on simplicity and speed. The moment you need hyphen breaks, reserved indentation, or max_lines with an ellipsis, stay on textwrap.


fill vs wrap in practice

textwrap.fill(text, width) is sugar for "\n".join(textwrap.wrap(...)) with the same kwargs. This lab’s fill vs wrap+join arms stayed within noise (~1240 vs ~1286 wraps/s at 1000 words). Choose based on whether you want a string or a list of lines for further processing (prefixing, numbering, boxed output).


Throughput vs features

The ~7–8× manual-pack win is real on synthetic ASCII words. It disappears as a product concern if wrap runs once per HTTP response and your handler already spends milliseconds on templates or DB. Profile first; micro-optimizing wrap is rarely the SRE win.


Pitfalls

  • Shipping hard-chunk “wrap” to UI users (broken words).
  • Re-wrapping on every keystroke without caching.
  • Assuming manual pack matches textwrap for tabs / CJK / combining characters.
  • Optimizing wrap before measuring — usually I/O or templating dominates.

Reproduce

python3 lab-evidence/89-textwrap-fill-vs-manual/results/run_lab.py

Evidence includes fixture_words_*.txt, summary.json.


Limits

One Linux box. ASCII-ish synthetic words. Width fixed at 72. Not terminal East-Asian width tables.


Takeaway

On 1000-word paragraphs, manual word-pack ~9632 wraps/s beat textwrap.fill ~1240 (~7.77×) with the same line count on this fixture. Default to textwrap.fill for correct, featureful wrapping; reach for a manual pack only when a profiler says so — and never confuse hard chunking with wrapping.

textwrap.filltextwrap.wrapmanual wrapparagraph wrappython textwraplocalhost labsrewraps/s

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. width=72. 1000 words: fill 1240/s; manual 9632/s (~7.77x); hard chunk 147102/s breaks words. fill and manual agreed on 88 lines for this fixture. Affiliates: 0. Evidence: lab-evidence/89-textwrap-fill-vs-manual.

Notes when a lab post goes up

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

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

  • Plate 88

    mmap Write vs pwrite Region: Localhost Lab

    Hands-on mmap MAP_SHARED write+msync vs pwrite region update: real MB/s with durability labels, measured on Linux localhost 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 — wraps/s (p50)
  5. Reading it
  6. What textwrap buys
  7. Fixture note
  8. When manual pack is enough
  9. fill vs wrap in practice
  10. Throughput vs features
  11. Pitfalls
  12. Reproduce
  13. Limits
  14. Takeaway
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove