是否存在一种误解,即没有比C更快的高级语言实现?

时间:2013-09-13 10:19:05

标签: c performance compiler-construction programming-languages scheme

虽然很难按语言对语言进行排名,但很明显,在实践中,今天你可以使用C获得最快的程序。我一直认为没有高级语言可以作为教条。至少在一段时间内快。除了我刚刚了解了Stalin compiler for Scheme。我们知道,Scheme是一种没有类型注释的高级函数语言。然而,该编译器声称生成的程序比中的直接等效值快1.5到100倍。

我不知道它存在的事实让我担心我的信念。首先,这怎么可能是真的?其次,这不可能是一个例外。还有其他高级或低级语言的编译器生成比C代码更快的代码,我也不知道吗?

5 个答案:

答案 0 :(得分:8)

你应该阅读评论......

  

很好,但是C版本很慢的部分原因是你使用的是abs而不是fabs。 abs将int作为参数(这应该是编译器警告!) - 传递除0之外的double总是返回一个大数字。 C版基本上是迭代的,直到误差低于双倍的分辨率。

     

的printf(“%d,%d \ n”个,ABS(0.0001)&LT 0.001,晶圆厂(0.0001)< 0.001);输出0,1

和回复

  

非常好!切换到晶圆厂使得gcc-inline的速度几乎与斯大林的速度相同。

文章的引用:

  

虽然原则上斯大林产生中间c代码,但它完全是外星人和低级别。

所以斯大林并不比C快,因为它编译为C,斯大林在编写比你难以理解的C代码方面更好: - )

来自维基页面:

  

斯大林(STAtic Language ImplementatioN)是Jeffrey Mark Siskind编写的一个积极的优化批量整个程序Scheme编译器。它使用高级流分析和类型推断以及各种其他优化技术来生成非常快速的代码(使用C作为中间语言),特别是对于数字代码。[引证需要]在许多测试中,它的性能优于手工 - 写作C,有时相当大的余量。[引证需要] Stalin用于生成优化的可执行文件。

所以让我们看看...这是一个编译器可能会尝试推断使用的类型(这个名称非常清楚)并且的表现优于手写 C

通常,域特定问题可能比C更快,因为它们可以使用C中不存在的技巧。例如,具有原始对象向量的语言可以更容易地使用CPU的向量指令。

答案 1 :(得分:2)

有人应该提到Fortran,它在数值应用程序中通常优于C语言。也许这很有帮助:

Fortran vs C++, does Fortran still hold any advantage in numerical analysis these days?

答案 2 :(得分:1)

任何给定语言的特定编译器都可能生成一个输出汇编程序,该程序比特定C编译器针对特定硬件目标的汇编输出更快。

所以是的,存在一些编程语言的实现,对于某些硬件,某些程序生成的程序集运行时间比“等效”的C程序少。

我所知道的“高级”语言没有比专业C程序员用C语言编写的所有程序的C编译器更好的汇编...

所以:

  • 存在级语言的编译器 至少有一个程序在编译时比C程序快。

  • 存在级语言的编译器 至少有一个程序在编译时比专家C快 程序

  • 级别语言的编译器适用于以上 编译时的一些程序比C程序快。

  • 对于大多数 级语言没有编译器 编写的程序产生的代码比同等专家C快 程序

使这个问题无法回答的事情:

  • “高级语言”的定义
  • “大多数程序”的定义 - 你真的是指>所有可能用语言枚举的程序的50%吗?
  • “比C更好”的定义 - 比天真的C更好?比专家C好吗?
  • 目标的定义 - 在所有架构上?一些特定的硬件?

参考文献:

答案 3 :(得分:1)

C - 使用编译器优化时 - 产生非常快的代码。我有一个由优秀的C编译器创建的后优化汇编程序代码,用于非常时间关键的中断。当知道编译器不知道的约束(例如,输入值总是在某个范围内)时,仍然可以使代码快25%。但是,Scheme编译器也不会知道!!

这意味着理论上编写代码的速度比C编译器生成的代码快1.3倍。但是,更难以加速代码。

另一种非常快的语言是Pascal,因此现代的Pascal变体(如FreePascal)可能与C编译器具有相同的运行时和内存消耗。

Scheme是一种声明性编程语言,而C是一种命令式编程语言。简单的问题是:“直接等价”是什么意思?

考虑以下Scheme代码:

(define (example a) (+ (if (> a 1)  (example (- a 1)) 0) (somefunc a)))

在C中你可以像这样实现它:

double iffunc(int a,double b,double c)
{
    return a?b:c;
}
double example(int a)
{
    return iffunc(a>1,example(a-1),0)+somefunc(a);
}

但你也可以像这样实现它:

double example(int a)
{
    int i;
    double b;
    for(i=1;i<=a;i++) b+=somefunc(i);
    return b;
}

在C中,第二个实现将是99%的程序员使用的实现。它比第一个快得多。第一个实现是Scheme变体的“直接等效”。 (在Scheme中写一个“for”-loop是不可能的!)

因此,如果您将第一个实现的速度与Scheme代码的速度进行比较,实际上可能会快1.5倍甚至更多。比较第二个实现的速度和Scheme编译器生成的代码,我确信C编译器会更快!

答案 4 :(得分:0)

这不是真的!

由于C使用程序集作为中间体,因此C在某个特定平台上永远永远不会 ,因此理论上不可能创建比实现者所能实现的代码更高效的代码手工。

对于编译为C的所有其他语言,您不能指望该语言优于同一作者编写的 C代码。斯大林是这样的语言,因为它的输出是生成C代码。如果Stalin的作者要在C中使用sqrt-iter,那么它将与他的Scheme编译器生成的C代码一样快。斯大林创造出比Justin Domke更有效的C代码,但这并不能证明斯大林比C更快。它只能证明斯大林的作者在C中比Justin Domke更好,因为他的知识在他的Scheme编译器中。 / p>

今天,C编译器使用静态分析,死代码消除,循环展开和各种优化技术。对于普通的程序员来说,C编译器可能拥有比低级代码生成的更好的代码,并且它更短更直观。更高级的语言抽象出不必要的元素,如内存管理,寄存器大小,指针和语法,使您的代码更小,更容易调试。它带有成本,通常是速度,但在许多情况下速度和有时内存使用,但它们不如效率重要。您可能听说过3 rules of optimization

最后,不同的编程语言将更适合不同的任务。选择Blogs算法选择作为一个很好的例子。你真的那样sqrt吗?我有过一次,但那是一种只有增量,减量和真实数学运算符的语言。

最后,我喜欢斯大林。对于一个非常了解C的人来说,这是一个很好的和平代码。应该研究它,但如果你真的想要运行Scheme,请考虑Ikarus。