- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 37MB
bin 文件,我正在尝试将其转换为 ppm 序列。它工作正常,我正在尝试将其用作练习来学习一些分析以及有关 Haskell 中惰性字节串的更多信息。我的程序似乎在 concatMap
处爆炸,它用于将每个字节复制三遍,所以我有 R、G 和 B。代码相当简单——我每 2048 个字节写一个新头:
{-# LANGUAGE OverloadedStrings #-}
import System.IO
import System.Environment
import Control.Monad
import qualified Data.ByteString.Lazy.Char8 as B
main :: IO ()
main = do [from, to] <- getArgs
withFile from ReadMode $ \inH ->
withFile to WriteMode $ \outH ->
loop (B.hGet inH 2048) (process outH) B.null
loop :: (Monad m) => m a -> (a -> m ()) -> (a -> Bool) -> m ()
loop inp outp done = inp >>= \x -> unless (done x) (outp x >> loop inp outp done)
process :: Handle -> B.ByteString -> IO ()
process h bs | B.null bs = return ()
| otherwise = B.hPut h header >> B.hPut h bs'
where header = "P6\n32 64\n255\n" :: B.ByteString
bs' = B.concatMap (B.replicate 3) bs
5s
多一点。这并不可怕,我唯一的比较是我非常幼稚的 C 实现,它在
4s
下完成了一点 - 所以这或理想情况下一直是我的目标。
33,435,345,688 bytes allocated in the heap
14,963,640 bytes copied during GC
54,640 bytes maximum residency (77 sample(s))
21,136 bytes maximum slop
2 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 64604 colls, 0 par 0.20s 0.25s 0.0000s 0.0001s
Gen 1 77 colls, 0 par 0.00s 0.01s 0.0001s 0.0006s
INIT time 0.00s ( 0.00s elapsed)
MUT time 5.09s ( 5.27s elapsed)
GC time 0.21s ( 0.26s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 5.29s ( 5.52s elapsed)
%GC time 3.9% (4.6% elapsed)
Alloc rate 6,574,783,667 bytes per MUT second
Productivity 96.1% of total user, 92.1% of total elapsed
70,983,992 bytes allocated in the heap
48,912 bytes copied during GC
54,640 bytes maximum residency (2 sample(s))
19,744 bytes maximum slop
1 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 204 colls, 0 par 0.00s 0.00s 0.0000s 0.0000s
Gen 1 2 colls, 0 par 0.00s 0.00s 0.0001s 0.0001s
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.01s ( 0.07s elapsed)
GC time 0.00s ( 0.00s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.02s ( 0.07s elapsed)
%GC time 9.6% (2.9% elapsed)
Alloc rate 5,026,838,892 bytes per MUT second
Productivity 89.8% of total user, 22.3% of total elapsed
-prof -auto-all -caf-all
找到其他瓶颈。
{-# LANGUAGE OverloadedStrings #-}
import System.IO
import System.Environment
import Control.Monad
import Data.Monoid
import qualified Data.ByteString.Builder as BU
import qualified Data.ByteString.Lazy.Char8 as BL
main :: IO ()
main = do [from, to] <- getArgs
withFile from ReadMode $ \inH ->
withFile to WriteMode $ \outH ->
loop (BL.hGet inH 2048) (process outH) BL.null
loop :: (Monad m) => m a -> (a -> m ()) -> (a -> Bool) -> m ()
loop inp outp done = inp >>= \x -> unless (done x) (outp x >> loop inp outp done)
upConcatMap :: Monoid c => (Char -> c) -> BL.ByteString -> c
upConcatMap f bs = mconcat . map f $ BL.unpack bs
process :: Handle -> BL.ByteString -> IO ()
process h bs | BL.null bs = return ()
| otherwise = BU.hPutBuilder h frame
where header = "P6\n32 64\n255\n"
bs' = BU.toLazyByteString $ upConcatMap trip bs
frame = BU.lazyByteString $ mappend header bs'
trip c = let b = BU.char8 c in mconcat [b, b, b]
6,383,263,640 bytes allocated in the heap
18,596,984 bytes copied during GC
54,640 bytes maximum residency (2 sample(s))
31,056 bytes maximum slop
1 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 11165 colls, 0 par 0.06s 0.06s 0.0000s 0.0001s
Gen 1 2 colls, 0 par 0.00s 0.00s 0.0001s 0.0002s
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.69s ( 0.83s elapsed)
GC time 0.06s ( 0.06s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.75s ( 0.89s elapsed)
%GC time 7.4% (7.2% elapsed)
Alloc rate 9,194,103,284 bytes per MUT second
Productivity 92.6% of total user, 78.0% of total elapsed
最佳答案
怎么样Builder ?
这个版本对我来说快了 5 倍:
process :: Handle -> B.ByteString -> IO ()
process h bs
| B.null bs = return ()
| otherwise = B.hPut h header >> B.hPutBuilder h bs'
where header = "P6\n32 64\n255\n" :: B.ByteString
bs' = mconcat $ map triple $ B.unpack bs
triple c = let b = B.char8 c in mconcat [b, b, b]
4,642,746,104 bytes allocated in the heap
390,110,640 bytes copied during GC
63,592 bytes maximum residency (2 sample(s))
21,648 bytes maximum slop
1 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 8992 colls, 0 par 0.54s 0.63s 0.0001s 0.0017s
Gen 1 2 colls, 0 par 0.00s 0.00s 0.0002s 0.0002s
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.98s ( 1.13s elapsed)
GC time 0.54s ( 0.63s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 1.52s ( 1.76s elapsed)
%GC time 35.4% (36.0% elapsed)
Alloc rate 4,718,237,910 bytes per MUT second
Productivity 64.6% of total user, 55.9% of total elapsed
关于performance - ByteString concatMap 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23501384/
是否可以并行执行高阶可观察对象,但在合并结果时仍保留顺序? 我有这样的东西: invoker$: Observable; fetch: (index: number) => Observable; i
我有这个设置: public listenCampaignSelected(){ var campaignSelected$ = this.store .select(store => s
这个问题在这里已经有了答案: Difference between concatMap f xs and concat $ map f xs? (1 个回答) 7年前关闭。 concatMap 是什么
我正在处理一组文件。对于每个文件,我需要请求正确的上传 URL,然后将该文件上传到正确的端点。 concatMap应该仅在前一个值完成后发出。这样,文件就应该被顺序处理。 这是我的代码: filesC
问题 7 来自 99 个 Haskell 问题 展平嵌套列表结构 这是我的解决方案: data NestedList a = Elem a | List [NestedList a] myFlatte
我有一个 37MB bin 文件,我正在尝试将其转换为 ppm 序列。它工作正常,我正在尝试将其用作练习来学习一些分析以及有关 Haskell 中惰性字节串的更多信息。我的程序似乎在 concatMa
我有以下代码: Observable.from(modifiedNodes) .concatMap(node => { return this.Model.setData(no
这个问题已经有答案了: Replace a 3 parameter list-comprehension by using map, concat (3 个回答) 已关闭 3 年前。 如何将列表理解转
我总体上很困惑,并正在寻找关于此代码如何工作的非常详细和解释性的答案: let xs = [1] ++ concatMap (\x -> [x+1,x*10]) xs in xs concatMap
这个问题已经有答案了: Replace a 3 parameter list-comprehension by using map, concat (3 个回答) 已关闭 3 年前。 如何将列表理解转
我在玩>>=今天,试图了解monads,发现了一个有趣的模式。使用列表单子(monad)时,>>=似乎表现得像 concatMap。我四处搜寻,试图找到任何相似之处,特别是在 hackage 的定义中
我试图找到一个行为类似于 concatMap 的运算符,但会丢弃介于两者之间的所有内容。例如, concatMap 执行以下操作: next a start handling a next b nex
可能是一个基本问题,但我有一个 Angular 应用程序调用后端服务来检索一些数据,然后使用该数据进行另一个后端服务调用。 第二次服务调用依赖于第一次成功完成,所以我使用 RxJS 的 concatM
我一直没能找到这个问题的答案,但是 concat map 之间有什么区别?和 map ?具体来说,我有一个让我很困惑的例子: const domainsObservable = this.auth.g
在Stream中我们可以通过flatMap将多维数据打开降维,扁平化处理数据为一维数据。Reactor当然也有这种需求,我们可以使用flatMap和concatMap进行数据的降维处理 flatMap
我读自Foldr Foldl Foldl'由于严格属性,foldl' 对于长的有限列表更有效。我知道它不适合无限列表。 因此,我只对长的有限列表进行比较。 连接映射 concatMap是使用 fold
考虑这个例子:我有一个文件按顺序下载。如果一个下载失败,它应该移动到下一个。伪代码: Observable.from(urls) .concatMap(url -> downloadObservab
我有一个 Observable 链和一个对话框,在一切都完成后会消失。顺序是这样的:1 api调用获取ResponseBody2 取response body进程(非ui线程)3个其他进程(不是ui线
我有 2 个 retrofit 电话需要进行 A 和 B: (A):返回一个ArrayList (B):获取 (A) 的结果,它是一个 ArrayList。 (B) 遍历 ArrayList 并使用每
我用 concatMap以长时间运行的操作一次处理一个项目流。在某些时候,我需要“中断”这个长时间运行的操作,但仅限于当前项目: @Test public void main() throws Int
我是一名优秀的程序员,十分优秀!