我目前正在对我的程序进行基准测试,看看我是否可以提高它的性能。目前我的程序将获取一个输入文件并运行一些算法将其拆分为多个文件。
将文件拆分为 3 部分大约需要 14 秒,其中-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 通常是瓶颈,但我想看看我是否可以提高我的程序的运行时性能。
干杯!