当前位置: 首页 > 知识库问答 >
问题:

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

柴默
2023-03-14

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

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
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
#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);
};

共有1个答案

楮星鹏
2023-03-14

GHC不会像C那样产生良好的紧密循环。根据我的经验,运行时的因数为3是正常的。

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

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
 类似资料:
  • 在这个打印从1到10000000的所有数字、Haskell版本和C版本的简单程序中,为什么Haskell版本如此缓慢,以及哪些命令有助于学习如何提高Haskell程序的性能? 下面是一份报告,包含重现我激动人心的事件所需的所有细节,制作报告时会打印出来源,包括Makefile的来源:

  • 问题内容: 当我遇到性能问题时,我只是更改了一个正在编写的程序,以将数据存储为numpy数组,而两者之间的区别令人难以置信。最初耗时30分钟,而现在耗时2.5秒! 我想知道它是如何做到的。我认为这是因为它消除了对循环的需要,但除此之外,我感到很困惑。 问题答案: 块状阵列是均质类型的密集堆积阵列。相比之下,Python列表是指向对象的指针数组,即使它们都属于同一类型。因此,您可以获得引用局部性的好

  • 它将把牌阵的一半分配给玩家和计算机(玩家得到前半部分,计算机得到后半部分)。现在这是先洗牌,所以是的,这似乎是公平的。 我得到的出界错误是这一行:

  • 这个sql查询要6s多,但是我两张表数据量都不是很大呀。box_api_data目前40000条,box_data_info目前10006条。基本都是比较少的,这么个数据量连接查询居然干到了6s,是我sql有问题吗?目前两张表都没有索引。

  • 它看起来有点像三元。要不是这样,我就会期望: 也许这是速记,但找到一个链接来确认是困难的。我在php4遗留代码中找到了这个片段。 (注意这是php而不是c#)

  • 问题内容: 我用 和做了一些测试 。他们似乎都慢于。是因为精度更高吗?计算斜边函数的方法是什么?令人惊讶的是,我在文档中找不到任何表明性能不佳的迹象。 问题答案: 这不是一个简单的sqrt函数。您应该检查此链接以实现算法:http : //www.koders.com/c/fid7D3C8841ADC384A5F8DE0D081C88331E3909BF3A.aspx 它具有while循环以检查收