Algorithm 如何提高此功能的性能?

Algorithm 如何提高此功能的性能?,algorithm,performance,haskell,recursion,optimization,Algorithm,Performance,Haskell,Recursion,Optimization,我试图在Haskell中实现一个接缝雕刻算法。我用的是-软件包 我想我差不多完成了,但是下面的函数使性能无法忍受+RTS-p-RTS评测告诉我它负责整个程序98%的时间和99%的alloc。 就是这样: f :: Image Pixel8 -> Int -> Int -> (Int,(Int,Int)) f img 0 r = (fromIntegral (pixelAt img 0 r),(r,0)) f img@(Image {..}) c r = maximumBy (c

我试图在Haskell中实现一个接缝雕刻算法。我用的是-软件包

我想我差不多完成了,但是下面的函数使性能无法忍受
+RTS-p-RTS
评测告诉我它负责整个程序
98%的时间
99%的alloc
。 就是这样:

f :: Image Pixel8 -> Int -> Int -> (Int,(Int,Int))
f img 0 r = (fromIntegral (pixelAt img 0 r),(r,0))
f img@(Image {..}) c r = maximumBy (comparing fst) [ ( (fst (f img (c-1) (r+j) )) + (fromIntegral (pixelAt img c r)) , (r+j,c-1) ) | j<-js ]
    where js | r==0 = [0,1]
             | r==(imageHeight-1) = [-1,0]
             | otherwise = [-1,0,1]
到目前为止,任何超过17岁的人都是我必须杀死的


如果有人能指出一些我可以在这里尝试的性能改进,我将不胜感激。这是我的第一个haskell项目,我已经很接近了

检查代码时,看起来您不止一次地计算某些值。具体地说,每次从
c
中减去
1
,都会传递
r
的一个值范围,并且随着减去的越多,范围也会增加。此外,不仅这些
r
值看起来有很多重叠,而且每个调用都会自己重复。简言之,您正在重新计算大量已经找到的结果

这似乎是一个非常经典的示例,您应该能够通过功能获得良好的性能提升。Haskell中有各种用于记忆的库,我不确定哪一个是最好的,但它们中的任何一个都可以降低计算的复杂性,这意味着它们中的任何一个都可以给您带来巨大的性能提升

一个可能有帮助的记忆工具是,它应该很容易使用。下面的代码应该可以为您实现这一点:

import Data.MemoTrie(memo2)
图像像素8->Int->Int->(Int,(Int,Int))
f img@(图像{..})=f'
哪里
f'=2前进
go 0 r=从积分(像素img 0 r),(r,0)

go c r=maximumBy(比较fst)[((fst(f’(c-1)(r+j)))+(from integral(pixelAt img c r)),(r+j,c-1))Jess!Jess!这正是丢失的东西。使用您的建议已经改进了<代码> C=17 < /代码>到<>代码> 0.308s从<代码> 20S。非常感谢它和解释!=)我建议您停止使用列表并尝试用手动循环重写算法,甚至更好地使用适当的数组库。ticular算法我建议在massiv中使用模具功能:还有massiv io包可以帮助您与JuicyPixels交互。
c=15 : 2.544s
c=16 : 7.025s
c=17 : 20.482s