相关疑难解决方法(0)

如何在Haskell中提高这种数值计算的性能?

我正在将David Blei的潜在Dirichlet分配的原始C实现移植到Haskell,我正在尝试决定是否在C中留下一些低级别的东西.以下函数是一个例子 - 它是一个近似值的二阶导数lgamma:

double trigamma(double x)
{
    double p;
    int i;

    x=x+6;
    p=1/(x*x);
    p=(((((0.075757575757576*p-0.033333333333333)*p+0.0238095238095238)
         *p-0.033333333333333)*p+0.166666666666667)*p+1)/x+0.5*p;
    for (i=0; i<6 ;i++)
    {
        x=x-1;
        p=1/(x*x)+p;
    }
    return(p);
}
Run Code Online (Sandbox Code Playgroud)

我把它翻译成或多或少惯用的Haskell如下:

trigamma :: Double -> Double
trigamma x = snd $ last $ take 7 $ iterate next (x' - 1, p')
  where
    x' = x + 6
    p  = 1 / x' ^ 2
    p' = p / 2 + c / x'
    c  = foldr1 (\a b -> …
Run Code Online (Sandbox Code Playgroud)

c math performance haskell

48
推荐指数
2
解决办法
4651
查看次数

您如何编写GHC中尽可能高效的数据结构?

所以有时我需要编写一个我在Hackage上找不到的数据结构,或者我发现没有经过测试或质量不足以让我信任,或者只是我不想成为依赖项.我现在正在阅读冈崎的书,它很擅长解释如何设计渐近快速的数据结构.

但是,我正在专门研究GHC.常数因素对我的应用来说是一个大问题.内存使用对我来说也是一个大问题.所以我对GHC有特别的疑问.

特别是

  • 如何最大化节点共享
  • 如何减少内存占用
  • 如何避免因严格不严/懒惰造成的空间泄漏
  • 如何让GHC为重要的代码段生成紧密的内部循环

我浏览了网络上的各个地方,我对如何使用GHC 有一个模糊的想法,例如,查看核心输出,使用UNPACK编译指示等.但我不确定我明白了.

所以我弹出了我最喜欢的数据结构库,容器,并查看了Data.Sequence模块.我不能说我理解他们正在做的很多事情,以使Seq快速.

引起我注意的第一件事就是定义FingerTree a.我认为这只是我对手指树不熟悉.引起我注意的第二件事是所有的SPECIALIZEpragma.我不知道这里发生了什么,我很好奇,因为这些都遍布整个代码.

许多函数也有一个INLINE与它们相关的编译指示.我可以猜到这意味着什么,但是如何判断何时INLINE起作用呢?

事情变得非常有趣~~475线,一个被称为"应用建筑"的部分.它们定义了一个newtype包装器来表示Identity monad,它们编写自己的严格状态monad副本,并且它们有一个被定义的函数applicativeTree,它显然专用于Identity monad,这增加了函数输出的共享.我不知道这里发生了什么.什么巫术被用来增加分享?

无论如何,我不确定从Data.Sequence中学到很多东西.是否有其他"模范程序"我可以阅读以获得智慧?我真的很想知道当我真正需要它们更快时,如何更新我的数据结构.有一件事特别是编写使融合变得容易的数据结构,以及如何编写良好的融合规则.

haskell data-structures

46
推荐指数
2
解决办法
2301
查看次数

标签 统计

haskell ×2

c ×1

data-structures ×1

math ×1

performance ×1