text-builder: Efficient and flexible strict text builder

[ builders, library, mit, text ] [ Propose Tags ] [ Report a vulnerability ]

Summary

Fast strict text builder and simple type-safe formatting library.

The Builder

The builder abstraction provided by this library is much faster than the standard lazy Builder and even the recently introduced StrictTextBuilder from "text". Benchmarks are distributed with the source code. You can see the results in the README file.

The abstraction constructs text in two phases. In the first one it estimates the size of the byte array and in the second one it allocates it once and populates it in one go.

Simple and type-safe formatting library

The monoidal API of the library provides a simple yet type-safe alternative to formatting strings via printf-like tools or more involved solutions like the popular "formatting" library.

Quality

Every bit of the library is heavily covered with tests with CI running tests on a variety of versions of GHC and the "text" library. This is crucial because the "text" library has made a switch from UTF-16 to UTF-8, leading to drastic changes in its low-level constructs, which builder libraries must rely on, and this library supports both versions of "text".

Ecosystem

Following is a list of libraries that, alongside this one, make an integrated ecosystem:

  • "text-builder-time" - formatters for the "time" library

  • "text-builder-core" - lower-level unsafe constructs for implementing efficient formatters compatible with this library

  • "text-builder-dev" - edge of development of new features providing a richer functionality at the cost of more frequent major releases

  • "text-builder-lawful-conversions" - integration with the "lawful-conversions" library, providing bidirectional conversions with various types including String, Data.Text.Text, Data.Text.Lazy.Text, Data.Text.Lazy.Builder.Builder, Data.Text.Encoding.StrictTextBuilder.


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.4, 0.4.1, 0.4.2, 0.4.3, 0.5, 0.5.1, 0.5.1.1, 0.5.2, 0.5.3, 0.5.3.1, 0.5.4, 0.5.4.1, 0.5.4.2, 0.5.4.3, 0.6, 0.6.1, 0.6.1.1, 0.6.1.2, 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.6.5.1, 0.6.6, 0.6.6.1, 0.6.6.2, 0.6.6.3, 0.6.6.4, 0.6.6.5, 0.6.6.6, 0.6.7, 0.6.7.1, 0.6.7.2, 0.6.7.3, 0.6.8, 0.6.9, 0.6.10, 1, 1.0.0.1, 1.0.0.2, 1.0.0.3, 1.0.0.4
Change log CHANGELOG.md
Dependencies base (>=4.11 && <5), bytestring (>=0.10 && <0.13), text (>=1.2 && <3), text-builder-core (>=0.1.1.1 && <0.2), time (>=1.12 && <2), transformers (>=0.5 && <0.7) [details]
License MIT
Copyright (c) 2017, Nikita Volkov
Author Nikita Volkov <nikita.y.volkov@mail.ru>
Maintainer Nikita Volkov <nikita.y.volkov@mail.ru>
Category Text, Builders
Home page https://github.com/nikita-volkov/text-builder
Bug tracker https://github.com/nikita-volkov/text-builder/issues
Source repo head: git clone https://github.com/nikita-volkov/text-builder
Uploaded by NikitaVolkov at 2025-05-30T11:32:19Z
Distributions Arch:0.6.7, Fedora:0.6.7.3, LTSHaskell:1.0.0.4, NixOS:0.6.10, Stackage:1.0.0.4
Reverse Dependencies 22 direct, 74 indirect [details]
Downloads 24079 total (144 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2025-05-30 [all 1 reports]

Readme for text-builder-1.0.0.4

[back to package description]

Summary

Fast strict text builder and simple type-safe formatting library for Haskell.

Performance

The benchmarks measure the monoidal composition of builders constructed from Text simulating left- and right-biased appends and mconcat.

The results show the following:

  • It's 2-3 times faster than the Data.Text.Lazy.Builder supplied with the "text" package.
  • It's 1.25 times faster than the Data.Text.Encoding.StrictTextBuilder which has recently arrived in "text".
  • It's 1.2-2 times faster than "text-builder-linear".
  • It's 1.1 times slower than Data.Text.Text in case of using mconcat over texts. In all other cases Text is slower and slows down exponentially, which is not surprising.

In the years of existence of this package multiple user-stories have been collected proving the performance boosts after switching to it.

All Competition Left-biased mappend 100B TextBuilder.TextBuilder: OK 187 ns ± 14 ns, 960 B allocated, 0 B copied, 6.0 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 215 ns ± 17 ns, 1.2 KB allocated, 0 B copied, 6.0 MB peak memory Data.Text.Lazy.Builder.Builder: OK 510 ns ± 27 ns, 2.6 KB allocated, 1 B copied, 6.0 MB peak memory Data.Text.Text: OK 216 ns ± 15 ns, 1.6 KB allocated, 0 B copied, 6.0 MB peak memory Data.Text.Lazy.Text: OK 424 ns ± 30 ns, 4.2 KB allocated, 2 B copied, 6.0 MB peak memory Data.Text.Builder.Linear: OK 368 ns ± 26 ns, 1.3 KB allocated, 0 B copied, 6.0 MB peak memory 1kB TextBuilder.TextBuilder: OK 1.54 μs ± 144 ns, 8.3 KB allocated, 8 B copied, 6.0 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 1.85 μs ± 131 ns, 12 KB allocated, 10 B copied, 6.0 MB peak memory Data.Text.Lazy.Builder.Builder: OK 4.66 μs ± 458 ns, 24 KB allocated, 31 B copied, 6.0 MB peak memory Data.Text.Text: OK 3.80 μs ± 257 ns, 104 KB allocated, 85 B copied, 6.0 MB peak memory Data.Text.Lazy.Text: OK 24.5 μs ± 1.7 μs, 358 KB allocated, 451 B copied, 6.0 MB peak memory Data.Text.Builder.Linear: OK 3.04 μs ± 213 ns, 12 KB allocated, 6 B copied, 6.0 MB peak memory 10kB TextBuilder.TextBuilder: OK 15.5 μs ± 1.2 μs, 82 KB allocated, 175 B copied, 8.0 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 18.3 μs ± 536 ns, 121 KB allocated, 439 B copied, 8.0 MB peak memory Data.Text.Lazy.Builder.Builder: OK 47.7 μs ± 3.4 μs, 242 KB allocated, 1.9 KB copied, 8.0 MB peak memory Data.Text.Text: OK 355 μs ± 19 μs, 9.6 MB allocated, 19 KB copied, 13 MB peak memory Data.Text.Lazy.Text: OK 2.63 ms ± 251 μs, 34 MB allocated, 264 KB copied, 13 MB peak memory Data.Text.Builder.Linear: OK 30.6 μs ± 1.7 μs, 110 KB allocated, 202 B copied, 13 MB peak memory 100kB TextBuilder.TextBuilder: OK 201 μs ± 14 μs, 1.0 MB allocated, 14 KB copied, 13 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 195 μs ± 19 μs, 1.2 MB allocated, 39 KB copied, 13 MB peak memory Data.Text.Lazy.Builder.Builder: OK 520 μs ± 30 μs, 2.4 MB allocated, 174 KB copied, 13 MB peak memory Data.Text.Text: OK 28.1 ms ± 2.0 ms, 954 MB allocated, 476 KB copied, 25 MB peak memory Data.Text.Lazy.Text: OK 616 ms ± 34 ms, 4.7 GB allocated, 136 MB copied, 25 MB peak memory Data.Text.Builder.Linear: OK 361 μs ± 33 μs, 1.5 MB allocated, 15 KB copied, 25 MB peak memory Right-biased mappend 100B TextBuilder.TextBuilder: OK 188 ns ± 13 ns, 960 B allocated, 0 B copied, 25 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 231 ns ± 17 ns, 1.2 KB allocated, 0 B copied, 25 MB peak memory Data.Text.Lazy.Builder.Builder: OK 500 ns ± 34 ns, 2.6 KB allocated, 1 B copied, 25 MB peak memory Data.Text.Text: OK 214 ns ± 18 ns, 1.6 KB allocated, 0 B copied, 25 MB peak memory Data.Text.Lazy.Text: OK 283 ns ± 13 ns, 1.8 KB allocated, 0 B copied, 25 MB peak memory Data.Text.Builder.Linear: OK 363 ns ± 19 ns, 1.3 KB allocated, 0 B copied, 25 MB peak memory 1kB TextBuilder.TextBuilder: OK 1.59 μs ± 123 ns, 8.3 KB allocated, 7 B copied, 25 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 1.98 μs ± 120 ns, 12 KB allocated, 9 B copied, 25 MB peak memory Data.Text.Lazy.Builder.Builder: OK 4.66 μs ± 281 ns, 24 KB allocated, 30 B copied, 25 MB peak memory Data.Text.Text: OK 3.76 μs ± 72 ns, 104 KB allocated, 79 B copied, 25 MB peak memory Data.Text.Lazy.Text: OK 2.23 μs ± 215 ns, 17 KB allocated, 29 B copied, 25 MB peak memory Data.Text.Builder.Linear: OK 3.03 μs ± 249 ns, 12 KB allocated, 11 B copied, 25 MB peak memory 10kB TextBuilder.TextBuilder: OK 15.6 μs ± 1.0 μs, 82 KB allocated, 205 B copied, 25 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 32.7 μs ± 2.0 μs, 185 KB allocated, 556 B copied, 25 MB peak memory Data.Text.Lazy.Builder.Builder: OK 47.6 μs ± 4.1 μs, 242 KB allocated, 2.1 KB copied, 25 MB peak memory Data.Text.Text: OK 437 μs ± 14 μs, 9.6 MB allocated, 22 KB copied, 28 MB peak memory Data.Text.Lazy.Text: OK 24.9 μs ± 1.0 μs, 168 KB allocated, 1.9 KB copied, 28 MB peak memory Data.Text.Builder.Linear: OK 30.4 μs ± 1.7 μs, 110 KB allocated, 427 B copied, 28 MB peak memory 100kB TextBuilder.TextBuilder: OK 176 μs ± 11 μs, 820 KB allocated, 18 KB copied, 28 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 363 μs ± 34 μs, 1.8 MB allocated, 51 KB copied, 28 MB peak memory Data.Text.Lazy.Builder.Builder: OK 561 μs ± 41 μs, 2.4 MB allocated, 191 KB copied, 28 MB peak memory Data.Text.Text: OK 31.4 ms ± 1.5 ms, 954 MB allocated, 379 KB copied, 36 MB peak memory Data.Text.Lazy.Text: OK 315 μs ± 13 μs, 1.6 MB allocated, 182 KB copied, 36 MB peak memory Data.Text.Builder.Linear: OK 333 μs ± 26 μs, 1.3 MB allocated, 34 KB copied, 36 MB peak memory mconcat 100B TextBuilder.TextBuilder: OK 125 ns ± 6.6 ns, 496 B allocated, 0 B copied, 36 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 166 ns ± 13 ns, 1.0 KB allocated, 0 B copied, 36 MB peak memory Data.Text.Lazy.Builder.Builder: OK 324 ns ± 27 ns, 2.1 KB allocated, 0 B copied, 36 MB peak memory Data.Text.Text: OK 117 ns ± 7.2 ns, 280 B allocated, 0 B copied, 36 MB peak memory Data.Text.Lazy.Text: OK 212 ns ± 17 ns, 1.7 KB allocated, 0 B copied, 36 MB peak memory Data.Text.Builder.Linear: OK 175 ns ± 13 ns, 936 B allocated, 0 B copied, 36 MB peak memory 1kB TextBuilder.TextBuilder: OK 1.21 μs ± 104 ns, 3.6 KB allocated, 1 B copied, 36 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 1.69 μs ± 117 ns, 9.8 KB allocated, 10 B copied, 36 MB peak memory Data.Text.Lazy.Builder.Builder: OK 3.04 μs ± 301 ns, 20 KB allocated, 16 B copied, 36 MB peak memory Data.Text.Text: OK 1.07 μs ± 74 ns, 2.0 KB allocated, 1 B copied, 36 MB peak memory Data.Text.Lazy.Text: OK 1.76 μs ± 154 ns, 16 KB allocated, 20 B copied, 36 MB peak memory Data.Text.Builder.Linear: OK 1.42 μs ± 58 ns, 8.0 KB allocated, 3 B copied, 36 MB peak memory 10kB TextBuilder.TextBuilder: OK 15.0 μs ± 838 ns, 35 KB allocated, 5 B copied, 36 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 32.0 μs ± 2.3 μs, 162 KB allocated, 563 B copied, 36 MB peak memory Data.Text.Lazy.Builder.Builder: OK 34.8 μs ± 1.7 μs, 202 KB allocated, 927 B copied, 36 MB peak memory Data.Text.Text: OK 10.6 μs ± 899 ns, 20 KB allocated, 5 B copied, 36 MB peak memory Data.Text.Lazy.Text: OK 22.0 μs ± 1.7 μs, 160 KB allocated, 1.3 KB copied, 36 MB peak memory Data.Text.Builder.Linear: OK 16.3 μs ± 1.4 μs, 71 KB allocated, 13 B copied, 36 MB peak memory 100kB TextBuilder.TextBuilder: OK 176 μs ± 15 μs, 352 KB allocated, 55 B copied, 36 MB peak memory Data.Text.Encoding.StrictTextBuilder: OK 437 μs ± 21 μs, 1.8 MB allocated, 78 KB copied, 36 MB peak memory Data.Text.Lazy.Builder.Builder: OK 333 μs ± 26 μs, 2.0 MB allocated, 84 KB copied, 36 MB peak memory Data.Text.Text: OK 106 μs ± 10 μs, 195 KB allocated, 60 B copied, 36 MB peak memory Data.Text.Lazy.Text: OK 264 μs ± 15 μs, 1.6 MB allocated, 97 KB copied, 36 MB peak memory Data.Text.Builder.Linear: OK 170 μs ± 8.1 μs, 952 KB allocated, 166 B copied, 36 MB peak memory Features intercalate TextBuilder: OK 420 ns ± 28 ns, 3.8 KB allocated, 1 B copied, 36 MB peak memory Text: OK 143 ns ± 9.9 ns, 824 B allocated, 0 B copied, 36 MB peak memory binary: OK 62.8 ns ± 3.7 ns, 152 B allocated, 0 B copied, 36 MB peak memory octal: OK 25.1 ns ± 1.7 ns, 96 B allocated, 0 B copied, 36 MB peak memory decimal: OK 48.5 ns ± 3.8 ns, 560 B allocated, 0 B copied, 36 MB peak memory hexadecimal: OK 20.8 ns ± 2.1 ns, 104 B allocated, 0 B copied, 36 MB peak memory 

How it works

It constructs text in two phases. In the first one it estimates the size of the byte array and in the second one it allocates it once and populates it in one go.