我正在学习Haskell,所以我试图实现移动平均函数。这是我的代码:在Haskell中计算移动平均值
mAverage :: Int-> [Int] -> [Float]
mAverage x a = [fromIntegral k/fromIntegral x | k <- rawAverage]
where
rawAverage = mAverage' x a a
-- First list contains original values; second list contains moving average computations
mAverage' :: Int -> [Int] -> [Int] -> [Int]
mAverage' 1 a b = b
mAverage' x a b = mAverage' (x - 1) a' b'
where
a' = init a
b' = zipWith (+) a' (tail b)
其中用户为每个平均和值的列表(例如mAverage 4 [1,2..100]
)的长度调用mAverage。
但是,当我在输入mAverage 4 [1,2..100000]
上运行代码时,我得到它在ghci中需要3.6秒(使用:set +s
),并使用了千兆字节的内存。这对我来说似乎效率很低,因为Python中的等效函数只需要几分之一秒。有什么方法可以让我的代码更高效?
注意:'初始化了'是_O(长度)_,有点贵。实现滑动窗口以便将其移出一个项目是恒定的时间将是很好的。 – 9000
GHCi不应该用于任何与性能有关的东西。我建议'ghc -O2'或'jhc'。 –
做滑动窗口的一种方法是将第一个总和作为“Float”传递,传入原始列表(用于从当前总和中减去)和原始列表,其中k个条目被丢弃(用于添加到当前总和)。然后,下一个和是传入的总和减去减法列表的第一个元素加上加法列表的第一个元素。 –