首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化管道管道

优化管道管道
EN

Stack Overflow用户
提问于 2014-05-25 16:56:14
回答 1查看 124关注 0票数 2

我目前正在对我的程序进行基准测试,看看我是否可以提高它的性能。目前,我的程序将获取一个输入文件,并运行一些算法将其拆分成多个文件。

将一个文件分成3个部分大约需要14秒,库和可执行文件都有-O2编译标志。

代码语言:javascript
复制
ghc-options:         -Wall -fno-warn-orphans -O2 -auto-all

看起来它在sinkFile上花费了大约60%的时间,我想知道我是否可以做些什么来改进下面的代码。

代码语言:javascript
复制
-- | 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性能分析的输出:

代码语言:javascript
复制
                                                                                                   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这样的小程序通常是瓶颈,但我想看看是否可以提高我的程序的运行时性能。

干杯!

EN

回答 1

Stack Overflow用户

发布于 2014-05-31 13:02:00

根据nh2的建议,我决定将ByteStrings打包成256字节的块,而不是在每个Word8实例上执行BS.singleton

代码语言:javascript
复制
cbs = CL.sequence (CL.take 256) =$= CC.map BS.pack

而不是

代码语言:javascript
复制
cbs = CC.map BS.singleton

而且我能够显著减少运行时间和内存使用量,如下所示:

原始运行

代码语言:javascript
复制
total time  =      194.37 secs   (194367 ticks @ 1000 us, 1 processor)
total alloc = 102,021,859,892 bytes  (excludes profiling overheads)

使用 CL.take新运行

代码语言:javascript
复制
total time  =       35.88 secs   (35879 ticks @ 1000 us, 1 processor)
total alloc = 21,970,152,800 bytes  (excludes profiling overheads)

这是一些很大的改进!我想对它进行更多的优化,但这是另一个问题:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23853592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档