Your example is slow because it uses lazy IO with String -s. Both have their own overhead.
In particular, String is a Char -s linked list, so it has two overhead service words for each character (one word for the constructor tag and one for the direct pointer), and each character takes at least one word (one word for cached low characters, three words for unescaped characters).
Strict I / O with byte or unicode input is much faster. Try the following tests:
import qualified Data.ByteString as B main = B.putStr =<< B.getContents
Or the following:
import qualified Data.Text as T import qualified Data.Text.IO as T main = T.putStr =<< T.getContents
source share