@@ -12,7 +12,10 @@
1212
1313module Data.Attoparsec
1414 (
15− -- * Performance
15+ -- * Differences from Parsec
16+ -- $parsec
17+
18+ -- * Performance considerations
1619 -- $performance
1720
1821 -- * Parser types
@@ -64,18 +67,52 @@ import Prelude hiding (takeWhile)
6467import qualified Data.Attoparsec.Internal as I
6568import qualified Data.ByteString as B
6669
70+-- $parsec
71+--
72+-- Compared to Parsec 3, Attoparsec makes several tradeoffs. It is
73+-- not intended for, or ideal for, all possible uses.
74+--
75+-- * While Attoparsec can consume input incrementally, Parsec cannot.
76+-- Incremental input is a huge deal for efficient and secure network
77+-- and system programming, since it gives much more control to users
78+-- of the library over matters such as resource usage and the I/O
79+-- model to use.
80+--
81+-- * Much of the performance advantage of Attoparsec is gained via
82+-- high-performance parsers such as 'I.takeWhile' and 'I.string'.
83+-- If you use complicated combinators that return lists of bytes or
84+-- characters, there really isn't much performance difference the
85+-- two libraries.
86+--
87+-- * Unlike Parsec 3, Attoparsec does not support being used as a
88+-- monad transformer. This is mostly a matter of the implementor
89+-- not having needed that functionality.
90+--
91+-- * Attoparsec is specialised to deal only with strict 'B.ByteString'
92+-- input. Efficiency concernts rule out both lists and lazy
93+-- bytestrings. The usual use for lazy bytestrings would be to
94+-- allow consumption of very large input without a large footprint.
95+-- For this need, Attoparsec's incremental input provides an
96+-- excellent substitute, with much more control over when input
97+-- takes place.
98+--
99+-- * Parsec parsers can produce more helpful error messages than
100+-- Attoparsec parsers. This is a matter of focus: Attoparsec avoids
101+-- the extra book-keeping in favour of higher performance.
102+
67103-- $performance
68104--
69105-- If you write an Attoparsec-based parser carefully, it can be
70−-- entirely reasonable to expect it to perform within a factor of 2 of
71−-- a hand-rolled C parser (measuring megabytes parsed per second).
106+-- realistic to expect it to perform within a factor of 2 of a
107+-- hand-rolled C parser (measuring megabytes parsed per second).
72108--
73109-- To actually achieve high performance, there are a few guidelines
74110-- that it is useful to follow.
75111--
76112-- Use the 'B.ByteString'-oriented parsers whenever possible,
77113-- e.g. 'I.takeWhile1' instead of 'many1' 'I.anyWord8'. There is
78−-- about a factor of 100 difference in performance between the two.
114+-- about a factor of 100 difference in performance between the two
115+-- kinds of parser.
79116--
80117-- For very simple byte-testing predicates, write them by hand instead
81118-- of using 'I.inClass' or 'I.notInClass'. For instance, both of