gpt4 book ai didi

Haskell - 如何编写惯用且高效的循环?

转载 作者:行者123 更新时间:2023-12-04 17:10:05 25 4
gpt4 key购买 nike

我对 Haskell 比较陌生,所以我正在解决一些旧的 Advent of Code 问题以熟悉该语言。
然而,我被困在了 2017 年的第 17 天,第二部分。
我已经尝试了三种解决方案来解决这个问题。
(编辑:将代码块简化为更清晰的示例)
以下解决方案是我希望适度有效地工作的东西:

run :: IO()
run = do
print "Starting:"
print (iteration''' 0 1 3 0 50000000)

iteration''' :: Int -> Int -> Int -> Int -> Int -> (Int, Int, Int, Int)
iteration''' cp cv ss zv 0 = (cp, cv, ss, zv)
iteration''' cp cv ss zv count = iteration''' ncp ncv ss nzv (count - 1)
where
ncp = ((cp + ss) `mod` cv) + 1
nzv = if ncp == 1 then cv else zv
ncv = cv + 1
问题是这三个方面的效率都非常低,无论是内存方面还是 CPU 方面。
等效的 C 代码将类似于以下内容(完成得非常快)。
int stepSize = 3;
int zv = 0;
int position = 0;
for (int i = 0; i < 50000000; i++) {
position = (position + stepSize) % i;
if (position == 0) zv = i;
}
我假设 iteration'''将能够编译为类似的东西 - 但它会占用数千兆字节的内存并长时间循环。
总结我的问题 - 在 Haskell 中“有效解决这个问题”的惯用方法是什么?当不需要实际的对象周转时,为什么它会占用这么多堆空间?
我正在使用 ghc (cabal) 进行编译。

最佳答案

为了完整起见,正如 Daniel Wagner 和 chi 所回答的那样:
所述代码中的问题是严格性(隐式地,大量惰性求值的整数会导致大量开销)。
这种方法要快得多(添加 BangPatterns header )

iteration''' :: Int -> Int -> Int -> Int -> Int -> (Int, Int, Int, Int)
iteration''' !cp !cv !ss !zv 0 = (cp, cv, ss, zv)
iteration''' !cp !cv !ss !zv !count = iteration''' ncp ncv ss nzv (count - 1)
where
ncp = ((cp + ss) `mod` cv) + 1
nzv = if ncp == 1 then cv else zv
ncv = cv + 1
我认为这意味着这也是编写(某些)高性能代码的惯用方式!

关于Haskell - 如何编写惯用且高效的循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69666642/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com