简而言之,不要使用read
。替换read
为以下函数:
import Numeric
fastRead :: String -> Int
fastRead s = case readDec s of [(n, "")] -> n
我得到了相当不错的加速:
~/programming% time ./test.slow
./test.slow 9.82s user 0.06s system 99% cpu 9.901 total
~/programming% time ./test.fast
./test.fast 6.99s user 0.05s system 99% cpu 7.064 total
~/programming% time ./test.bytestring
./test.bytestring 4.94s user 0.06s system 99% cpu 5.026 total
只是为了好玩,上述结果包括一个使用ByteString
ULTIMATE BARE-MetaL SPEED的版本(因此完全忽略了文件编码问题,因此未能通过“ 21世纪的就绪”测试)。它还有一些其他差异。例如,它附带了标准库的排序功能。完整代码如下。
import qualified Data.ByteString as BS
import Data.Attoparsec.ByteString.Char8
import Control.applicative
import Data.List
parser = many (decimal <* char '\n')
reallyParse p bs = case parse p bs of
Partial f -> f BS.empty
v -> v
main = do
numbers <- BS.readFile "data"
case reallyParse parser numbers of
Done t r | BS.null t -> writeFile "sorted" . unlines . map show . sort $ r