這是我想出來的。
我使用了JB提供的功能,並添加了我從bytestring-lexing的源代碼中學到的兩個技巧(謝謝,sclv!)。第一個是這樣的功能:
strict = SB.concat . LB.toChunks
它把一個懶惰字節串到非延遲一個有效。
第二個技巧是函數Data.ByteString.Internal.inlinePerformIO
,它是unsafePerformIO的一個更高效的變體。
下面是完整的代碼,允許一個相當快的數字閱讀:
{-# LANGUAGE ForeignFunctionInterface #-}
import qualified Data.ByteString.Lazy.Char8 as LB
import qualified Data.ByteString as SB
import Data.ByteString.Internal (inlinePerformIO)
import Foreign.C.String (CString)
import Foreign.C (CDouble)
import Data.Maybe (fromJust)
foreign import ccall unsafe "stdlib.h atof" c_atof :: CString -> IO Double
unsafeReadDouble = inlinePerformIO . flip SB.useAsCString c_atof
{-# INLINE unsafeReadDouble #-}
readDouble = unsafeReadDouble . SB.concat . LB.toChunks
readInt = fst . fromJust . LB.readInt
這計算輸入所有數字的總和示例程序:
main = LB.getContents >>= (print . sum . map readDouble . LB.lines)
It processes an 11Mb file (1M numbers) in about 0.5 seconds
I also found several links , where a much more efficient version of readInt
進行了討論。據推測,人們可以根據類似的想法建立一個readDouble
。但是我想現在我會堅持使用我目前的版本。
只需安裝字節串,詞法分析器包即可。 「cabal install bytestring-lexer」 – sclv 2010-12-20 16:41:01
我想在沒有附加包的情況下執行操作,因爲我的程序將在我無法控制的服務器上運行。 – adamax 2010-12-20 18:34:20
@adamax:值得向你的問題添加限制。 – 2010-12-20 20:36:29