Keep in mind in all comparisons to GNU wc that it does extra work, detecting multi-byte characters and decoding multi-byte characters if present, to correctly count the number of words. perf shows a significant amount of time being spent in multibyte character handling. If you trigger a code path that does not do decoding beyond the byte level, it’s much faster:
$ time wc wiki-large.txt
854100 17794000 105322200 wiki-large.txt
wc wiki-large.txt 0.42s user 0.02s system 99% cpu 0.438 total
$ time wc -l wiki-large.txt
854100 wiki-large.txt
wc -l wiki-large.txt 0.02s user 0.02s system 98% cpu 0.034 total
(wc -l looks at every byte, but does no decoding.)From a quick glance, this is also where the 'Haskell beats C' article fails. It’s comparing apples to oranges, the ByteString implementation does not do the same as GNU/macOS wc and returns incorrect results in the presence of non-ASCII punctuation. The article incorrectly states that wc will handle input as ASCII. Unless you do not use a multi-byte locale, macOS wc uses the combo of mbrtowc and iswspace.