He is only parsing the headers in the final Haskell version, and skipping the body. In the C++ version, he also seems to check the MD5 and/or SHA1 hash (if a hash of the body available and OpenSSL with SHA1/MD5 support is available).
So, it's not exactly clear to me if the C++ and the Haskell version are still doing the same thing. Also, in the C++ version he is parsing stuff by hand, it will probably a lot faster when using a proper lexer (you usually can't beat an optimized finite state machine ;)) and parser.
Unfortunately, the emphasis on performance distracts from the main point: parsers written with attoparsec or parsec are usually understandable, type-safe, and pretty, while offering performance near to that of a C/C++ version.
In other words, if you have enough time, you can probably come up with a C or C++ parser that is as fast or faster than a Haskell-based parser (assuming some overhead of boxing/unboxing, garbage collection, more difficult optimization, ...), but would you care if the Haskell implementation had 80% of the performance and was far more maintainable?
So, it's not exactly clear to me if the C++ and the Haskell version are still doing the same thing. Also, in the C++ version he is parsing stuff by hand, it will probably a lot faster when using a proper lexer (you usually can't beat an optimized finite state machine ;)) and parser.
Unfortunately, the emphasis on performance distracts from the main point: parsers written with attoparsec or parsec are usually understandable, type-safe, and pretty, while offering performance near to that of a C/C++ version.
In other words, if you have enough time, you can probably come up with a C or C++ parser that is as fast or faster than a Haskell-based parser (assuming some overhead of boxing/unboxing, garbage collection, more difficult optimization, ...), but would you care if the Haskell implementation had 80% of the performance and was far more maintainable?