Performance 函数的有效表示

Performance 函数的有效表示,performance,function,haskell,language-theory,Performance,Function,Haskell,Language Theory,函数类型A->B在某种意义上不是很好。虽然函数是一级值,但由于效率问题,人们通常无法自由操作它们。你不能应用太多的转换A->B->C->D,在某些时候你必须计算一个值 显然,这是由于->的非严格性质造成的 处理Double->Double类型的函数有很多众所周知的技巧。我们可以将它们表示为给定一定基的向量,它可以由三角函数、多项式等组成 A->B类型的效率低下,有什么通用的解决办法吗 或->的替代方法?最常用的技巧之一是记忆-在计算函数值后存储函数值。链接:。正如你所提到的,另一个技巧是当你有一

函数类型A->B在某种意义上不是很好。虽然函数是一级值,但由于效率问题,人们通常无法自由操作它们。你不能应用太多的转换A->B->C->D,在某些时候你必须计算一个值

显然,这是由于->的非严格性质造成的

处理Double->Double类型的函数有很多众所周知的技巧。我们可以将它们表示为给定一定基的向量,它可以由三角函数、多项式等组成

A->B类型的效率低下,有什么通用的解决办法吗


或->的替代方法?

最常用的技巧之一是记忆-在计算函数值后存储函数值。链接:。正如你所提到的,另一个技巧是当你有一个很好的函数类型多项式、向量、泰勒级数等-然后它可以表示为一个列表、表达式等。

最常用的技巧之一是记忆-在计算后存储函数的值。链接:。正如你提到的,另一个技巧是当你有一个很好的函数类型多项式、向量、泰勒级数等-然后它可以表示为一个列表、表达式等。

你关心的似乎是给定h===f•g,f•g通常比h效率低。给定编译时已知的函数组合,编译器执行两种技巧可以使f•g比您想象的更高效—内联和融合。内联避免了第二个函数调用的额外间接性,并为优化打开了许多新的机会。流融合或build/foldr融合可以提供一个基本的示例,如地图f。把g映射成f。从而将结构的遍历次数减少一个常数因子。Fusion不仅在列表上运行,而且在其他结构上运行,它为Haskell库(如Vector)的高效性能提供了一个原因

捷径融合:


流融合:

您关心的似乎是给定h==f•g,f•g的效率通常低于h。给定编译时已知的函数组合,编译器执行两种技巧可以使f•g比您想象的更高效—内联和融合。内联避免了第二个函数调用的额外间接性,并为优化打开了许多新的机会。流融合或build/foldr融合可以提供一个基本的示例,如地图f。把g映射成f。从而将结构的遍历次数减少一个常数因子。Fusion不仅在列表上运行,而且在其他结构上运行,它为Haskell库(如Vector)的高效性能提供了一个原因

捷径融合:


流融合:

我无法确认这一点。作为AFRP的高效用户和实现者,我经常在完全多态的函数上执行转换,这些函数嵌套得很深,并且用于长时间运行的应用程序。请注意,Haskell编译器不使用传统的基于堆栈的函数调用范式。他们使用图形简化算法。我们没有像C一样的问题。

我不能证实这一点。作为AFRP的高效用户和实现者,我经常在完全多态的函数上执行转换,这些函数嵌套得很深,并且用于长时间运行的应用程序。请注意,Haskell编译器不使用传统的基于堆栈的函数调用范式。他们使用图形简化算法。比如说,我们没有与C.相同的问题。

FWIW:在Felix中,函数参数有三种:急切的、懒惰的,或者由编译器决定

在对函数体求值之前,将求值并将参数赋值给变量

惰性参数的计算方法是在参数出现的任何位置用参数表达式替换参数

默认值是由编译器决定。对于大量的普通代码,不管这意味着什么,无论您使用的是急切的还是懒惰的求值都没有任何区别

一般来说,在Felix中,惰性计算更快:请注意,这并不意味着闭包。这意味着内联。然而,有时编译器会选择急切求值,这会减少代码膨胀,过多的内联会适得其反。我不认为算法是好的。。然而,费利克斯有时会表现得比C好,而Ocaml GHC没有进入决赛

举个简单的例子。。类型类。Felix有类型类,有点像Haskell。没有或很少的性能开销。。当然没有字典

在我看来,如果你抛弃了单独编译的陈旧概念,Haskell会好得多:整个程序分析器可以做更多的事情,而且如果完全自由地缓存编译结果,文本处理比目标代码快得多。是的 让一种懒惰的语言使用一种为急切的评估而设计的编译模型是疯狂的


Haskell变体可能尝试的另一件事是放弃所有函数都是惰性的想法,而是采用评估策略无关的想法,除非另有规定。这可能会带来更多的优化机会。

FWIW:Felix是一个全程序分析器,它严重依赖内联来获得性能,函数参数有三种:急切、懒惰或由编译器决定

在对函数体求值之前,将求值并将参数赋值给变量

惰性参数的计算方法是在参数出现的任何位置用参数表达式替换参数

默认值是由编译器决定。对于大量的普通代码,不管这意味着什么,无论您使用的是急切的还是懒惰的求值都没有任何区别

一般来说,在Felix中,惰性计算更快:请注意,这并不意味着闭包。这意味着内联。然而,有时编译器会选择急切求值,这会减少代码膨胀,过多的内联会适得其反。我不认为算法是好的。。然而,费利克斯有时会表现得比C好,而Ocaml GHC没有进入决赛

举个简单的例子。。类型类。Felix有类型类,有点像Haskell。没有或很少的性能开销。。当然没有字典

在我看来,如果你抛弃了单独编译的陈旧概念,Haskell会好得多:整个程序分析器可以做更多的事情,而且如果完全自由地缓存编译结果,文本处理比目标代码快得多。让一种懒惰的语言使用为急切的评估而设计的编译模型是疯狂的


Haskell变体可能尝试的另一件事是放弃所有函数都是惰性的想法,而是采用评估策略无关的想法,除非另有规定。这可能会带来更多的优化机会。

这种效率低下的程度实际上取决于应用程序。通常,函数的自然A->B表示是很好的,当有更好的表示时,总是需要利用某类函数的某些特殊特性;例如,当使用Double->Double函数的三角基时,你假设这些函数是光滑的,有界的,在紧致区间上平方可积的,等等。没有这样的假设,就没有有用的规范替代表示,因此就不可能有真正的通用技巧。显然,这种[低效率]是由于->的非严格性质造成的,这对我来说并不明显。这个问题对Haskell来说似乎也不是特别的;这是一个与编程语言理论有关的相当普遍且有点模糊的问题。这种低效到底有多低效取决于应用程序。通常,函数的自然A->B表示是很好的,当有更好的表示时,总是需要利用某类函数的某些特殊特性;例如,当使用Double->Double函数的三角基时,你假设这些函数是光滑的,有界的,在紧致区间上平方可积的,等等。没有这样的假设,就没有有用的规范替代表示,因此就不可能有真正的通用技巧。显然,这种[低效率]是由于->的非严格性质造成的,这对我来说并不明显。这个问题对Haskell来说似乎也不是特别的;这是一个与编程语言理论有关的相当普遍且有点模糊的问题。嗯,事实上,我记得,不久前当我遇到这个问题时,我打算深入记忆。但是后来我换了别的东西,没能做到。嗯,事实上,我记得,不久前,当我遇到这个问题时,我打算深入记忆。但后来我换了别的东西,没能成功。