功能语言本身就很慢吗?

时间:2009-02-05 15:14:40

标签: compilation functional-programming

为什么函数式语言总是在基准测试中落后于C?如果你有一个静态类型的函数式语言,在我看来它可以被编译成与C相同的代码,或者甚至更优化的代码,因为编译器可以使用更多的语义。为什么看起来所有函数式语言都比C慢,为什么它们总是需要垃圾收集和过度使用堆?

是否有人知道适用于嵌入式/实时应用程序的函数式语言,其中内存分配保持在最低限度且生成的机器代码是精简且快速的?

9 个答案:

答案 0 :(得分:17)

什么都不是。以下是interpreted OCaml runs faster than equivalent C code的示例,因为OCaml优化器由于语言不同而具有不同的可用信息。当然,一般声称OCaml明显比C更快是愚蠢的。重点是,这取决于你在做什么,以及你是如何做的。

尽管如此,OCaml是(大部分)函数式语言的一个例子,实际上是为performance而设计的,与纯度相反。

答案 1 :(得分:11)

功能语言需要消除在语言抽象层次上可见的可变状态。因此,需要复制由命令性语言在适当位置发生变异的数据,并在副本上进行突变。举一个简单的例子,请参阅Haskell与C的快速排序。

此外,垃圾收集是必需的,因为free()不是纯函数,因为它有副作用。因此,在语言抽象层次上释放不涉及副作用的内存的唯一方法是使用垃圾收集。

当然,原则上,足够智能的编译器可以优化大部分复制。这已经在某种程度上已经完成,但是让编译器足够聪明地理解代码在该级别的语义只是很难。

答案 2 :(得分:9)

C很快,因为它基本上是汇编程序的一组宏:)当你用C语言编写程序时,没有“幕后”。当你决定这样做的时候分配内存而你在同样的时尚。当您编写实时应用程序时,这是一个巨大的优势,其中可预测性很重要(实际上比其他任何事情都重要)。

此外,C编译器通常非常快,因为语言本身很简单。它甚至不进行任何类型检查:)这也意味着更容易找到错误。 缺少类型检查的广告优势是,函数名称只能以其名称导出,例如,这使得C代码易于与其他语言的代码链接

答案 3 :(得分:8)

答案简短:因为C很快。就像在,快速疯狂地疯狂。一种语言根本不需要“缓慢”才能被C语言交给它。

C之所以快,是因为它是由非常优秀的编码人员创建的,而gcc在几十年的时间里已经过优化,而且还有数十名出色的编码人员,而不是99%的语言。

简而言之,除了需要非常特殊的函数式编程结构的专业任务之外,你不会打败C语言。

答案 4 :(得分:6)

对于语言的控制流程更好地匹配现代计算机的实际处理模式。

C非常接近地映射到其编译产生的汇编代码,因此昵称为“跨平台汇编”。计算机制造商花了几十年的时间使汇编代码尽可能快地运行,因此C继承了所有这些原始速度。

相比之下,功能语言的无副作用,固有的并行性并不能很好地映射到单个处理器上。可以调用函数的任意顺序需要序列化到CPU瓶颈:如果没有非常聪明的编译,你将成为上下文切换所有的时间,没有任何预取将会工作,因为你经常跳到那里,...基本上,计算机制造商为优秀,可预测的临时语言所做的所有优化工作都是无用的。

然而!随着向许多功能较弱的核心(而不是一个或两个带有涡轮增压的核心)的转变,功能语言应该开始缩小差距,因为它们自然地水平扩展。

答案 5 :(得分:5)

就目前而言,功能语言并未大量用于行业项目,因此没有足够的认真工作进入优化工具。此外,为命令式目标优化命令式代码可能更容易。

功能语言有一个壮举,可以让它们很快超越命令式语言:琐碎的并行化。

琐碎不是因为它很容易,但它可以构建到语言环境中,而不需要开发人员考虑它。

像C这样的线程无关的语言中强大的多线程的成本对许多项目来说都是禁止的。

答案 6 :(得分:4)

好的Haskell只比GCC的C ++慢1.8倍,这比典型的基准测试任务的GCC C实现要快。 这使得Haskell非常快,甚至比C#(Mono)更快。

相对语言 速度

  • 1.0 C ++ GNU g ++
  • 1.1 C GNU gcc
  • 1.2 ATS
  • 1.5 Java 6 -server
  • 1.5清洁
  • 1.6 Pascal Free Pascal
  • 1.6 Fortran Intel
  • 1.8 Haskell GHC
  • 2.0 C#Mono
  • 2.1 Scala
  • 2.2 Ada 2005 GNAT
  • 2.4 Lisp SBCL
  • 3.9 Lua LuaJIT

source

对于记录我在iPhone上使用Lua for Games,因此如果您愿意,可以轻松使用Haskell或Lisp,因为它们更快。

答案 7 :(得分:2)

我不同意tuinstoel。重要的问题是功能语言是否提供了更快的开发时间,并且当它被用于使用哪些函数语言时会产生更快的代码。请参阅efficiency issues section on Wikipedia,了解我的意思。

答案 8 :(得分:1)

更大的可执行文件大小的另一个原因可能是延迟评估和非严格性。当编译某些表达式时,编译器无法在编译时弄清楚,因此一些运行时被填充到可执行文件中以处理此问题(调用所谓的 thunks 的评估)。至于表现,懒惰既好又坏。一方面,它允许额外的潜在优化,另一方面,代码大小可以更大,并且程序员更可能做出错误的决定,例如请参阅Haskell的 foldl foldr foldl' foldr'