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}!双重
hmatrix
)的库集成。因此,作为输入/输出,我广泛使用Data.Vector.Storablenewtype 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。由于不同的评估顺序,这是一个双精度舍入问题吗?我将研究它;我需要执行什么才能看到你描述的行为?