- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我读自Foldr Foldl Foldl'由于严格属性,foldl'
对于长的有限列表更有效。我知道它不适合无限列表。
因此,我只对长的有限列表进行比较。
concatMap
是使用 foldr
实现的,这给了它惰性。然而,根据这篇文章,将它与长的有限列表一起使用将建立一个长的未缩减链。
concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
concatMap f xs = build (\c n -> foldr (\x b -> foldr c b (f x)) n xs)
因此我想出了以下使用 foldl'
的实现方式。
concatMap' :: Foldable t => (a -> [b]) -> t a -> [b]
concatMap' f = reverse . foldl' (\acc x -> f x ++ acc) []
我构建了以下两个函数来测试性能。
lastA = last . concatMap (: []) $ [1..10000]
lastB = last . concatMap' (: []) $ [1..10000]
然而,我对结果感到震惊。
lastA:
(0.23 secs, 184,071,944 bytes)
(0.24 secs, 184,074,376 bytes)
(0.24 secs, 184,071,048 bytes)
(0.24 secs, 184,074,376 bytes)
(0.25 secs, 184,075,216 bytes)
lastB:
(0.81 secs, 224,075,080 bytes)
(0.76 secs, 224,074,504 bytes)
(0.78 secs, 224,072,888 bytes)
(0.84 secs, 224,073,736 bytes)
(0.79 secs, 224,074,064 bytes)
concatMap
在时间和内存方面都胜过我的 concatMap'
。我想知道我在 concatMap'
实现中犯了错误。
因此,我怀疑那些描述foldl'
优点的文章。
concatMap
是不是有什么黑魔法让它如此高效?
foldl'
对于长的有限列表更有效是真的吗?
使用带有长有限列表的 foldr
是否真的会建立一个长的未缩减链并影响性能?
最佳答案
Are there any black magic in concatMap to make it so efficient?
不,不是真的。
Is it true that
foldl'
is more efficient for long finite list?
并不总是。这取决于折叠功能。
重点是,foldl
和 foldl'
在生成输出之前总是必须扫描整个输入列表。相反,foldr
并不总是必须这样做。
作为一个极端的例子,考虑
foldr (\x xs -> x) 0 [10..10000000]
立即计算为 10
——仅计算列表的第一个元素。减少就像
foldr (\x xs -> x) 0 [10..10000000]
= foldr (\x xs -> x) 0 (10 : [11..10000000])
= (\x xs -> x) 10 (foldr (\x xs -> x) 0 [11..10000000])
= (\xs -> 10) (foldr (\x xs -> x) 0 [11..10000000])
= 10
由于懒惰,递归调用没有被评估。
一般来说,在计算foldr f a xs
时,重要的是检查f y ys
是否能够在 评估 ys
。例如
foldr f [] xs
where f y ys = (2*y) : ys
在评估 2*y
和 ys
之前生成列表单元格 _ : _
。这使它成为 foldr
的绝佳候选者。
同样,我们可以定义
map f xs = foldr (\y ys -> f y : ys) [] xs
运行得很好。它使用 xs
中的一个元素并输出第一个输出单元格。然后它消耗下一个元素,输出下一个元素,依此类推。使用 foldl'
在处理整个列表之前不会输出任何内容,这使得代码效率很低。
相反,如果我们写
sum xs = foldr (\y ys -> y+ys) 0 xs
然后我们在 xs
的第一个元素被消耗后不输出任何东西。我们构建了一长串 thunk,浪费了大量内存。在这里,foldl'
将改为在恒定空间中工作。
Is it true that using
foldr
with long finite lists will build up a long unreduced chain and impact the performance?
并不总是。这在很大程度上取决于调用者如何使用输出。
作为一个经验法则,如果输出是“原子的”,意味着输出消费者不能只观察到它的一部分(例如 Bool, Int, ...
)那么最好是使用 foldl'
。如果输出是由许多独立值(列表、树等)“组成”的,如果 f
可以逐步生成其输出,则 foldr
可能是更好的选择-step,以“流式”方式。
关于为有限列表使用 foldl' 实现 concatMap 的性能提升?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43033099/
我有一个关于复杂性的简单问题。我在 Java 中有这段代码: pairs是 HashMap包含 Integer作为键,它的频率为 Collection作为一个值。所以: pairs = new Has
对于我的应用程序,我需要在 Coq 中使用和推理有限映射。谷歌搜索我发现 FMapAVL 似乎非常适合我的需求。问题是文档很少,我还没有弄清楚我应该如何使用它。 作为一个简单的例子,考虑以下使用对列表
我有一个主表tblAssetMaster A和一个移动表tblMovement M。 我想提取所有 Assets 及其当前位置,因此需要获取每个 Assets 的最新移动条目。 字段 A: Asset
我想让我的网站内容居中,但仅限于网页的特定宽度。所以当它超过 500px 时,我希望内容被修复,无法进一步拉伸(stretch)。无论如何都要这样做,还是我最好把所有东西都修好?希望有意义的是添加一些
我正在尝试批量删除 Backbone 模型的集合,如下所示...... collection.each(function(model, i){ model.destroy(); }); 我发现当每
我想要一个软件环境,在其中我可以在具有特定资源的硬件上测试我的软件的速度。例如,当我的主机硬件是具有 12GB RAM 的 3GHz 四核 amd64 时,该程序在具有 24 Mb RAM 的 800
在 Eclipse 中,我得到了 BigInteger.valueOf(2).pow(31093) 的值,但没有得到 BigInteger.valueOf(2).pow(31094) 的值(它是空的)
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度理解。包括尝试过的解决方案、为什么它们不起作用,以及预
我想将 2 个表从本地 sql server 2000 上传到托管的 mysql。第一个表有 17 列和 680 行,其他 10 列和 8071 行。 我首先使用 xampp mysql 尝试离线,它
我在 S3 中自动生成并保存了静态 html 文件。有时文件大小达到 2mb。是否可以使用javascript来获取html文件的一部分,显示它,当用户到达页面底部时,获取下一部分等等? 最佳答案 X
我是一名优秀的程序员,十分优秀!