哪种最大选择算法更快? (哈斯克尔)[重复]

Posted

技术标签:

【中文标题】哪种最大选择算法更快? (哈斯克尔)[重复]【英文标题】:Which maximum selection algorithm is faster? (Haskell) [duplicate] 【发布时间】:2021-12-19 13:41:06 【问题描述】:

我怀疑这是第一个,但我不确定,也不知道如何检查,所以我想我就在这里发帖。我也有点懒得提供普通的例子,但是类型的东西 基本上与我的问题无关。

data Storage = HDD String Int Int
             | SSD String Int
             deriving(Show,Eq)

maxSSD :: [Storage] -> Int -> Int
        maxSSD (HDD:xs) mx = maxSSD xs mx
        maxSSD [] mx = mx
        maxSSD l@((SSD _ x):xs) (-1) = maxSSD l x
        maxSSD ((SSD _ x):xs) mx
            |x>mx = maxSSD xs x
            |otherwise = maxSSD xs mx

maxSSD' :: [Storage] -> Int
        maxSSD (HDD:xs) = maxSSD xs
        maxSSD [] = 0
        maxSSD ((SSD _ x):xs) 
                |x>(maxSSD xs) = x
                |True = maxSSD xs 

【问题讨论】:

我认为maxSSD' 甚至不会像写的那样编译;它应该是递归的,而不是调用maxSSD,对吗? @Pillsy 调用 self(在减少的输入上)是递归的。 我有点不确定关闭是否正确。这个 Q 询问它的具体代码和算法:一个是迭代的,另一个是递归的,而不是像建议的副本那样一般。 也许有人会想评论严格性分析器对性能的影响或其他什么...如果您需要我重新打开它,请联系我。 @提问者:你认为“重复”回答了你的问题吗? 【参考方案1】:

NB:当然缩进是错误的(签名的缩进和定义应该是一样的),我假设第二个代码中的所有maxSSDs实际上都是maxSSD's。我>

从表面上看,第一个是线性的,第二个是最坏情况下的指数,在某些情况下计算递归调用 (maxSSD' xs) 两次。

但是由于该表达式参与了 > 比较,并且 > 在两个参数中都是严格的,如果您使用优化 (-O2) 进行编译,则严格分析器有望启动,从而防止重新计算相同的价值。

您可以通过使用-O2 编译并使用-RTS +s 运行已编译的独立可执行文件来进行测试,以获取时间和空间统计信息,然后在几个不同的问题规模上运行它,例如,每次加倍。然后看看运行时间是否也加倍。

另见:Empirical orders of growth

一般而言,我们可以说第一个代码表示迭代算法,第二个代码表示递归算法。

对第二个的简单调整将防止重新计算相同值的任何可能性:

只需酌情使用let / where 子句来引入保存递归调用结果的绑定,然后引用该变量两次。这样可以保证只计算一次。

【讨论】:

以上是关于哪种最大选择算法更快? (哈斯克尔)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

哈斯克尔,再次。非法类型? [关闭]

使用scanl时空间泄漏在哪里? (哈斯克尔)

`ghc-pkg` 和 `cabal` 程序有啥关系? (哈斯克尔)

哈斯克尔。我很困惑这个代码片段是如何工作的

哈斯克尔中类型的函数应用操作数($)?

哪个选择查询将运行得更快[重复]