【发布时间】:2011-08-17 07:41:48
【问题描述】:
我目前正在从事一个小型项目(
我想学习更多的函数式编程并希望获得更多的类型安全性,例如将可变计算包装到状态转换器单子等中。为此,存在 scalaz 库。
问题一
当通过使用所有花哨的功能性东西在更大规模上抽象我的计算时,我会引入我无法摆脱的性能杀手吗?就像我的计算在 Monads 中被包裹得很深?
问题二
考虑到 Scala 的有限类型推断,这是否可行?我目前正在与非常大的类型签名作斗争(可能是因为我不知道如何正确摆脱它们)。我想更多的“功能”会引入更多这样的样板代码。
免责声明
我不是在质疑函数式方法的好坏。向 Haskell 提出这个问题是没有意义的。我质疑 Scala 这样做是否明智。
按需编辑:我的项目中的大型类型签名示例
(但这将是一个不同的问题)
以下代码描述了对类型参数化输入对象 (DiscreteFactorGraph[VariableType, FactorType[VariableType]]) 的迭代计算。你可以用createInitialState构造一个计算对象,用advanceState对其进行计算,最后用marginals从中提取一些信息。
我希望在计算过程中保留因子图对象的类型(及其参数类型),以便marginals 的最终应用产生正确的DiscreteMarginals[VariableType] 类型。我认为目前我只需要在计算类型中保留变量类型(即TState),因此不使用携带因子类型。但在不同的地方,我什至需要 DiscreteFactorGraph 的类型是可变的,所以我倾向于在未来需要更多的类型信息通过计算。
我一直在摆弄这部分,希望有更好的解决方案。目前我有一个非常实用的方法,其中只有这三个功能。但我必须通过它们链接类型。或者,我可以将其定义为一个类并使用所有这些类型为该类参数化,因此我不必为每个方法重复类型参数。
object FloodingBeliefPropagationStepper extends SteppingGraphInferer {
def marginals[V <: DiscreteVariable, F <: DiscreteFactor[V]](state: FloodingBeliefPropagationStepper.TState[V,F]): DiscreteMarginals[V] =
BeliefPropagation.marginals(state._1, state._2)
def advanceState[V <: DiscreteVariable, F <: DiscreteFactor[V]](state: FloodingBeliefPropagationStepper.TState[V,F]): FloodingBeliefPropagationStepper.TState[V,F] = {
val graph = state._1
(graph,
BeliefPropagation.computeFactorMessages(
graph,
BeliefPropagation.computeVariableMessages(graph, state._2, graph.variables),
graph.factors))
}
def createInitialState[V <: DiscreteVariable, F <: DiscreteFactor[V]](graph: DiscreteFactorGraph[V, F],
query: Set[V],
random: Random): FloodingBeliefPropagationStepper.TState[V,F] = {
(graph,
BeliefPropagation.computeFactorMessages(
graph,
BeliefPropagation.createInitialVariableMessages(graph, random),
graph.factors))
}
type TState[V <: DiscreteVariable, F <: DiscreteFactor[V]] = (DiscreteFactorGraph[V,F],Map[(F,V),DiscreteMessage])
}
【问题讨论】:
-
你能举一个或几个你的大字体签名的例子吗?
-
你的类型签名是无法管理的,因为你选择了像
FloodingBeliefPropagationStepper.TState这样长得令人难以置信的名字。如果您追求高性能解决方案,使用DiscreteVariable而不是Int或类似的可能会导致最大的性能损失(除非您实际上需要对变量做很少的事情)。到目前为止,代码看起来像是为了最大化抽象而不是性能而编写的。那么你真的应该对性能有多担心呢? -
@Rex
DiscreteVariable只是对变量本身的描述,不保存任何状态(用于保存计算状态的具体数据结构是在“问题规范”的较低级别创建的" 由图表描述)。实际上,您正在查看一个抽象类,并且计算处于较低级别,例如BeliefPropagation。 -
@ziggystar - 好的,在这种情况下,很难判断使用 Scalaz 是否会对性能产生负面影响,因为您没有提供有关正在执行哪种计算的任何详细信息。因此,答案是“也许”。
-
作为编写大量高性能代码的人,我可以向您保证,如果您不小心地将数据打包成可以可变计算的原始类型,您的代码在大多数情况下都会执行与 C++ 之类的相比较差。斯卡拉兹也不例外。不过,我还不能评论 Scalaz 与非 Scalaz 函数式不可变样式的相对性能,这就是为什么这是评论而不是答案。
标签: performance scala scalaz