【发布时间】:2016-06-08 14:39:23
【问题描述】:
我从 Haskell 开始,对如何为我通常用 C 或 Python 编写的简单代码获得匹配的性能感兴趣。考虑以下问题。
给你一个长度为 n 的长字符串 1 和 0。我们想要为每个长度为m 的子字符串输出该窗口中 1 的数量。也就是说,输出在0 和m 之间具有n-m+1 不同的可能值。
在 C 中,这很简单,时间与n 成正比,并使用与m 位成正比的额外空间(在存储输入所需的空间之上)。您只需计算长度为m 的第一个窗口中 1 的数量,然后维护两个指针,一个指向窗口的开头,一个指向结尾,并根据一个指向 1 和其他点来递增或递减为 0 或发生相反的情况。
是否有可能在 Haskell 中以纯函数的方式获得相同的理论性能?
一些糟糕的代码:
chunkBits m = helper
where helper [] = []
helper xs = sum (take m xs) : helper (drop m xs)
main = print $ chunkBits 5 [0,1,1,0,1,0,0,1,0,1,0,1,1,1,0,0,0,1]
【问题讨论】:
-
请注意 Haskell 使用惰性编程。在某些情况下,例如,如果您只对前五个数字感兴趣,则时间复杂度可能为 O(1)。
-
@WillemVanOnsem 在这种情况下,您需要读取 m+4 位,不是吗?
-
@eleanora:考虑到您的窗户面向未来,是的。如果它回顾过去,它只需要前 4 个(或 m,如果 m 更小)。
-
好吧,这不是一件坏事,但您应该从自己的一些实现开始,并演示它们如何不提供所需的性能。
-
@MattJordan
m可能不依赖于 int 字符串的长度,但如果算法不包含固定的m作为其定义的一部分。
标签: algorithm performance pointers haskell time-complexity