Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何在Haskell中优化数值库的速度_Performance_Haskell_Optimization - Fatal编程技术网

Performance 如何在Haskell中优化数值库的速度

Performance 如何在Haskell中优化数值库的速度,performance,haskell,optimization,Performance,Haskell,Optimization,我发布了一个用于求解延迟微分方程的小型数值库: 主要技术限制: 使库在动态变量数量(x(t),y(t),…)方面具有灵活性,即给定时刻动态系统的状态 轻松与利用Data.Vector.Storable(例如hmatrix)的库集成。因此,作为输入/输出,我广泛使用Data.Vector.Storable 因此,与此解决方案不同: , 使用的是newtype State=State{u State::V.Vector Double} 而不是data State=State{-#UNPACK}!双重

我发布了一个用于求解延迟微分方程的小型数值库:

主要技术限制:

  • 使库在动态变量数量(x(t),y(t),…)方面具有灵活性,即给定时刻动态系统的状态
  • 轻松与利用Data.Vector.Storable(例如
    hmatrix
    )的库集成。因此,作为输入/输出,我广泛使用Data.Vector.Storable
  • 因此,与此解决方案不同: , 使用的是
    newtype State=State{u State::V.Vector Double}
    而不是
    data State=State{-#UNPACK}!双重{-#解包{-}!双击
    。但是,该库现在运行速度慢了两倍


    问题:是否有任何方法可以同时提高
    数据状态=状态{-#解包{-}…
    的速度和
    新类型状态=状态{u状态::V.Vector Double}
    对于未指定数量的变量的灵活性?在编译时,我应该考虑模板Haskell来创建<代码>数据解包< /代码>类结构吗?< /P> < P>我不使用任何特定的向量实现。变量长度类型(如
    Data.Vector
    )是一个糟糕的选择,这不仅是因为当空间维度较低时,额外的长度信息是一个相当大的开销,还因为您失去了任何类型系统保证维度匹配

    相反,您应该在选择向量空间时使所有内容参数化。也就是说,可以有效地将维度设置为编译时变量,并允许向量类型具有一些有意义的命名子变量

    import Data.VectorSpace
    import Data.AdditiveGroup
    
    newtype Stepper1 state = Stepper1 {
      _stepper
        ::  Double
        -> RHS state   -- parameterised in a similar way
        -> state
        -> (Double, Double)
        -> (Double, Double)
        -> state
      }
    
    rk₄ :: VectorSpace v => Stepper1 v
    rk₄ = Stepper1 _rk4
     where _rk4 hStep rhs' y₀ ... = y₀ ^+^ (h/6)*^(k₁ ^+^ 2*^k₂ ^+^ 2*^k₃ ^+^ k₄)
             where k₁ = rhs' (y₀, ...)
                   k₂ = rhs' (y₀ ^+^ (h/2)*^k₁, ...)
                   k₃ = rhs' (y₀ ^+^ (h/2)*^k₂, ...)
                   k₄ = rhs' (y₀ ^+^ h*^k₃, ...)
    
    然后,用户可以选择它的具体实现。对于二维向量,标准选择来自
    线性
    包;它与来自的
    VectorSpace
    实例一起重新导出。但对于测试,您也可以只使用普通的元组,其中有一个
    VectorSpace
    实例。当然,环绕
    hmatrix
    中的类型也是可能的,但这对性能并没有好处——如果需要,最好只转换最终结果

    为了获得最佳性能,您可能需要使用一些
    {-#INLINE#-}
    杂注。Bong模式通常不会带来太多性能优势——最重要的是类型是严格的,并且没有绑定。当然,在每个变量定义之前先发制人是没有用的——这些都不会产生任何影响,因为CAF只有在使用时才会被评估


    我很高兴听到你最后的表演!如果它明显比你原来的
    状态{-#UNPACK#-}更糟糕!双重{-#解包{-}!Double
    ,这是我们应该调查的。

    您导入了哪些模块作为
    V
    ?从装箱到未装箱向量的切换非常类似于从
    data State=State Double Double
    切换到
    data State=State{-#UNPACK}!双重{-#解包{-}!双击
    。要回答您的问题,
    导入符合条件的Data.Vector.Storable as V
    ,请参见感谢您的优雅回答!我肯定会考虑到这一点。我花了一段时间来实现这一点:Haskell类型的系统看起来相当复杂。这是新版本。代码现在更加优雅,但是没有明显的加速。最简单的比较方法是
    堆栈构建和时间堆栈执行mackey glass>/dev/null
    ,此外,由于某些原因,master和dev分支的结果并不相同。我很想知道为什么。首先,结果略有不同,然后,很自然地,它们会出现分歧。但不超过1e-13。由于不同的评估顺序,这是一个双精度舍入问题吗?我将研究它;我需要执行什么才能看到你描述的行为?