Haskell算法之间的渐近差异

时间:2015-11-03 10:45:53

标签: haskell optimization ghc asymptotic-complexity

这里我们需要得到给定长度的所有子序列。如何计算给定函数的渐近复杂度?

import Data.List

subsequencesOfSize l n = [x | x <- subsequences l, length x == n]

多少&#34;迭代&#34;那将会?我们可以谈论&#34;迭代&#34;。任何优化? GHC 7.10.2。编译器或程序员如何改进这个?

2 个答案:

答案 0 :(得分:1)

我认为你的问题包含至少2个不同的问题,但是GHC的当前版本是否可以优化这个

subsequencesOfSize l n = [x | x <- subsequences l, length x == n]

类似

subsequencesOfSize l n = [x | x <- subsequences l, lengthIsGt n x, length x == n]

非常值得怀疑 - 我还不是优化,超级编译等方面的专家,但是在这里使用lengthIsGt来推断像length这样的东西的需要似乎非常重要并且不太可能成为编译器的一组通用优化的一部分。

P.S。实际上,如果在包含lengthIsGt的条件(但无论如何都是伪代码)之前评估包含length的条件,lengthIsGt的版本仍可能会尝试评估无限列表

答案 1 :(得分:1)

这是一个相关的SO问题,讨论了subsequencesOfSize的各种实现:

Haskell: comparison of techniques for generating combinations

是使用记忆的最佳表现:

Haskell: comparison of techniques for generating combinations

<强>更新

还要考虑@ user3237465在评论中提到的这个版本:

subsequencesOfSize :: Int -> [a] -> [[a]]
subsequencesOfSize n xs | n > length xs = []
subsequencesOfSize n xs = subsequencesBySize xs !! n where
    subsequencesBySize    []  = [[[]]]
    subsequencesBySize (x:xs) = zipWith (++) ([] : map (map (x:)) next) (next ++ [[]])
        where next = subsequencesBySize xs