2
我目前正在對我的程序進行基準測試,以查看我是否可以提高其性能。目前我的程序會接收一個輸入文件並運行一些算法將其分成多個文件。優化管道管道
將文件拆分爲3部分大約需要14s,對於庫和可執行文件都使用-O2
編譯標誌。
ghc-options: -Wall -fno-warn-orphans -O2 -auto-all
看起來它會耗費其時間大約60%的sinkFile
,我想知道是否有什麼我可以做,以改善下面的代碼。
-- | Get the sink file, a list of FilePaths and the share number of the file to output to.
idxSinkFile :: MonadResource m
=> [FilePath]
-> Int
-> Consumer [Word8] m()
idxSinkFile outFileNames shareNumber =
let ccm = CC.concatMap $ flip atMay shareNumber
cbs = CC.map BS.singleton
sf = sinkFile (outFileNames !! shareNumber)
in ccm =$= cbs =$= sf
-- | Generate a sink which will take a list of bytes and write each byte to its corresponding file share
sinkMultiFiles :: MonadResource m
=> [FilePath]
-> [Int]
-> Sink [Word8] m()
sinkMultiFiles outFileNames xs =
let len = [0..length xs - 1]
in getZipSink $ otraverse_ (ZipSink . idxSinkFile outFileNames) len
這裏是GHC的分析的輸出:
individual inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
splitFile.sink HaskSplit.Conduit.Split 289 1 0.0 0.0 66.8 74.2
sinkMultiFiles HaskSplit.Conduit.Split 290 1 27.4 33.2 66.8 74.2
idxSinkFile HaskSplit.Conduit.Split 303 3 7.9 11.3 39.4 41.0
idxSinkFile.ccm HaskSplit.Conduit.Split 319 3 3.1 3.6 3.1 3.6
idxSinkFile.cbs HaskSplit.Conduit.Split 317 3 3.5 4.2 3.5 4.2
idxSinkFile.sf HaskSplit.Conduit.Split 307 3 24.9 21.9 24.9 21.9
sinkMultiFiles.len HaskSplit.Conduit.Split 291 1 0.0 0.0 0.0 0.0
這都說明sinkFile
採取了大量的時間。 (我已經基準列表訪問等,如果你想知道,他們有0%的處理)
雖然我理解像這樣的小程序IO往往是瓶頸,我想看看我是否可以提高我的程序的運行時性能。
乾杯!
這可能是更多的信息,重新編譯'管道'和'conduit-extra'以'-auto-all'以及更詳細的地方看時間正在耗費。 –
@MichaelSnoyman,嗯,我更希望這是我做得不對的事情。我會盡量深入挖掘。從過去的經驗來看,你有沒有一個「sinkFile」速度的粗略例子? –
我不知道這是否與你的程序有關,但一些Web服務器像方法/ warp使用blaze-builder來構建可以有效輸出的ByteStrings – yokto