2

While it is hard to rank languages by speed, it is well accepted that, in practice, today, you can get the fastest programs using C. I've always taken as a dogma that no high-level language could be as fast as it at least for some time. Except I've just learned about the Stalin compiler for Scheme. Scheme, as we know, is a high-level functional language with no type annotation. Yet, that compiler claims to generate programs 1.5 to 100 times faster than their direct equivalent in C.

The fact I wasn't aware of its existence makes me worry about my beliefs. First, how can that be true? Second, this can't be a lone exception. Are there other compilers of high or low level languages that are producing faster-than-C code, that I am not aware of too?

4

5 回答 5

8

你应该看看评论...

很好,但 C 版本速度慢的部分原因是您使用的是 abs 而不是 fabs。abs 接受一个 int 作为参数(这应该是一个编译器警告!)——传递一个非零的 double 总是返回一个大数字。C 版本基本上是迭代直到错误低于双精度。

printf(“%d,%d\n”,abs(0.0001)<0.001,fabs(0.0001)<0.001); 输出 0,1

和回应

好点!切换到 fabs 使 gcc-inline 的速度几乎完全降低到斯大林的水平。

以及文章中的引述:

尽管原则上斯大林会产生中间的 c 代码,但它完全是陌生的和低级的。

所以斯大林并不比 C 快,因为它编译为 C,斯大林比你更擅长编写紧凑的不可读的 C 代码:-)

从维基页面:

Stalin(静态语言实现)是由 Jeffrey Mark Siskind 编写的一个积极优化的批处理全程序方案编译器。它使用高级流分析和类型推断以及各种其他优化技术来生成非常快的代码(使用 C 作为中间语言),特别是对于数字代码。[需要引用] 在许多测试中,它的性能都优于手动用 C 写的,有时有相当大的余量。[需要引用] 斯大林旨在用于生成优化的可执行文件的生产用途。

所以让我们看看......它是一个编译器,它可能试图推断使用的类型(这个名字很清楚)并且它的性能优于手写的C

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

于 2013-09-13T10:32:34.207 回答
2

有人应该提到 Fortran,它在数值应用中通常优于 C。也许这会有所帮助:

Fortran 与 C++,如今 Fortran 在数值分析中是否仍然具有优势?

于 2013-09-13T15:12:55.197 回答
2

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

这意味着理论上可以编写比 C 编译器生成的代码快 1.3 倍的代码。然而,进一步加快代码速度是不可能的。

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

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

考虑以下方案代码:

(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”循环是不可能的!!)

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

于 2013-09-13T13:27:34.877 回答
1

这不是真的!

在特定平台上, C永远不会比汇编快,因为 C 使用汇编作为中间体,因此 C 理论上不可能创建比其实现者手动完成的代码更高效的代码。

对于编译为 C 的所有其他语言,您不能期望该语言的性能优于同一作者编写的 C 代码。斯大林就是这样的语言,因为它的输出是生成的 C 代码。如果斯大林的作者要在 C 中执行 sqrt-iter,那将是一个与他的 Scheme 编译器生成的 C 代码一样快的 C。斯大林创建的 C 代码比 Justin Domke 手工创建的 C 代码效率更高,但这并不能证明斯大林比 C 更快。这只能证明斯大林的作者在 C 方面比贾斯汀多姆克更好,因为他的知识在他的 Scheme 编译器中。

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

最后,不同的编程语言将更适合不同的任务。算法的博客选择被选为一个很好的例子。你真的会那样做sqrt吗?我有一次,但那是一种只有递增、递减和 while-true 作为数学运算符的语言。

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

于 2013-09-13T15:39:40.100 回答
1

任何给定语言的特定编译器可以生成输出汇编程序,该程序比来自特定硬件目标的特定 C 编译器的汇编输出更快。

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

据我所知,对于由专业 C 程序员用 C 编写的所有程序,没有任何“高级”语言可以比好的 C 编译器生成更好的汇编......

所以:

  • 存在用于高级语言的编译器,其中至少有一个程序在编译时比 C 程序快。

  • 存在用于高级语言的编译器,其中至少有一个程序在编译时比专家 C 程序更快。

  • 存在用于高级语言的编译器,对于多个程序而言,它们在编译时比 C 程序更快。

  • 对于大多数程序编写的高级语言没有编译器 生成的代码比等效的专家 C 程序更快。

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

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

参考:

于 2013-09-13T10:37:19.680 回答