gpt4 book ai didi

performance - 为什么这个 Haskell 数组填充操作这么慢?

转载 作者:行者123 更新时间:2023-12-04 03:26:23 25 4
gpt4 key购买 nike

对于特定任务,我需要在可变数组中进行大量快速、单独的写入。为了检查性能,我使用了以下测试:

size :: Int
size = 256*256*16

arr :: UArray Int Int
arr = runST $ do
arr <- newArray (0,size) 0 :: ST s (STUArray s Int Int)
forM_ [0..size] $ \i -> do
writeArray arr i i
unsafeFreeze arr

arr_sum = foldl' (\ sum i -> sum + (arr ! i)) 0 [0..size-1]

main = print arr_sum

结果如下:
vh:haskell apple1$ ghc -O3 bench.hs -o bench; time ./bench
Linking bench ...
549755289600

real 0m0.748s
user 0m0.697s
sys 0m0.048s

我怀疑在内存上填充一个 256*256*16 的数组不应该需要 0.7s,所以我在 JavaScript 中测试了一个等效的程序:
size = 256*256*16;
x = new Array(size);
s = 0;
for (var i=0; i<size; ++i)
x[i] = i;
for (var i=0; i<size; ++i)
s += x[i];
console.log(s);

结果是:
vh:haskell apple1$ time node bench.js
549755289600

real 0m0.175s
user 0m0.150s
sys 0m0.024s

在 C 上,时间是 0.012s ,这是一个很好的下界。
#include <stdio.h>

#define SIZE (256*256*16)
double x[SIZE];

int main(){
int i;
double s = 0;
for (i = 0; i<SIZE; ++i)
x[i] = i;
for (i = 0; i<SIZE; ++i)
s += x[i];
printf("%f",s);
};

所以这几乎证实了我的假设,即我的 Haskell 程序正在做其他事情,而不仅仅是填充数组并在之后求和。某处可能有一个隐藏的堆栈,但我无法识别它,因为我使用了 foldl'forM_ ,我相信它被编译为无堆栈代码。那么,这里效率低下的根源是什么?

最佳答案

GHC 不会像您使用 C 完成的那样产生良好的紧密循环。根据我的经验,运行时间的系数为 3 大约是类(class)的标准。

要获得更好的性能,请使用 Vector 库:

import qualified Data.Vector.Unboxed as V

size = 256*256*16 :: Int

doit = V.foldl' (+) 0 vec
where vec = V.generate size id

main = print doit

关于performance - 为什么这个 Haskell 数组填充操作这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28035350/

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