【问题标题】:Is it a misconception that there are no higher level languages implementations faster than C? [closed]没有比 C 更快的高级语言实现是一种误解吗? [关闭]
【发布时间】:2013-09-13 10:19:05
【问题描述】:

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

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

【问题讨论】:

  • “比 C 代码更快”到底是什么意思? C 代码始终使用编译器进行编译。你指的C编译器是什么?
  • @G_G,有些事情很难定义。你知道我的意思,这里的普通读者也会知道。在大多数情况下,斯大林生成的代码比使用任何 C 编译器(例如 gcc)编译的等效 C 程序(定义复杂的另一个术语,但您知道我的意思)更快。不过,我无法证明这一点:我刚刚得到了他们的说法。但是我已经完成了研究,并且互联网上的许多轶事证实了这些,所以我至少在最初对此充满信心。
  • 是和不是。是的,如果一个非常优秀的 C 程序员坐下来查看代码足够长的时间,可能会找到某种方法使其至少与汇编以外的任何其他代码一样快。然而,对于很长一段代码的普通到优秀的程序员来说,你的一次性优秀高级语言很可能比一次性的 C 语言更快。 flownet.com/gat/papers/lisp-java.pdf

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


【解决方案1】:

你应该阅读 cmets...

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

printf(“%d,%d\n”,abs(0.0001)

和回应

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

以及文章中的引用:

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

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

来自维基页面:

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

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

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

【讨论】:

  • 他们让它的运行速度和斯大林一样快,考虑到 Scheme 是一种已知在大多数实现中比 C 慢一个数量级的动态语言,这仍然令人印象深刻。另外,我听说过一些轶事,一般来说,斯大林制作的程序实际上比它们的 C 等效程序快得多,所以我对这个很有信心。
  • @Viclib 我将添加文章中的另一个引用:Though in principle Stalin produces intermediate c code, it is utterly alien and low-level.。所以重点不是斯大林比 C 快,而是斯大林写的 C 代码比你好:-)
  • @Viclib 它是动态的这一事实无关紧要。如果可以在编译时扣除类型,则编译后的代码与静态类型化代码一样优化。
  • 当然,这是可能的——我对此没有异议。但是,其他高级语言的编译器是否平均比语言 C 代码生成得更快——就像斯大林所做的那样?而且,为什么 C 经常被推荐用于性能敏感的应用程序,当有这个看似更好的选择时?为什么没有更多的人使用斯大林?
  • @Viclib 对于第二个问题...从技术上讲,C++ 是一种与 C 不同的语言,但对于相同的代码,它会产生类似的机器代码,所以它应该同样快。通过使用模板编程,某些类型的问题甚至可以在编译时解决,使得 C++ 理论上更快:-)
【解决方案2】:

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

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

【讨论】:

  • "我相信 C 编译器会更快!" - 这是一个有品位的测试邀请!
  • @Viclib:我测试了它(不幸的是,Scheme 编译器似乎只是整数,所以我不得不使用整数进行测试):Scheme:26 个计时器滴答声(32 个包括中断),C:6 个计时器滴答声(-> C 比 Scheme 快 4 倍!)
  • 好吧,你赢了。那 4 个月是关于斯大林的编译时间吗?
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

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

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

    所以:

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

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

    • 存在高级语言的编译器,超过 一些程序在编译时比 C 程序快。

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

    让这个问题无法回答的原因:

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

    参考资料:

    【讨论】:

    • 唐,虽然我同意你所说的大部分内容,但我认为你错了,因为斯大林符合最后的描述。除非您在使用“专家”一词时有点过分——公平的比较涉及两个语义相似的程序,事实上,斯大林在这方面的表现几乎总是优于 C。
    • 如果所讨论的语言很少用于其擅长的用途之外的任何目的,那么大多数用特定领域语言编写的程序都可以胜过任何合理的 C 实现几乎是不可能的。例如,如果一个系统有一个 GPU 需要在切换缓冲区时清除其管道,但在设置“主剪切矩形”时不需要,那么特定于域的语言可能能够检查应用程序需要使用的缓冲区集单个较大缓冲区的区域来处理它们。
    • 特定领域的语言可能是图灵完备的,并且可能允许代码动态指定缓冲区大小(当代码这样做时执行速度有些慢),但对于大多数实际为它编写的应用程序来说,它能够使用静态分析将事物排序到 C 编译器无法做到的程度。一个人可能有一个 C 例程,它会在运行时获取一系列必要的操作并找出如何最好地处理它们,但这基本上需要用 C 编写一个 GPU 操作编译器。
    • 是的,DSL 是一个很好的例外。我们在这里假设“高级”+“通用”。
    【解决方案5】:

    这不是真的!

    C从不在特定平台上比 Assembly 快,因为 C 使用汇编作为中间体,因此理论上 C 不可能创建比其实现者更高效的代码可以做 em> 手工。

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

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

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

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

    【讨论】:

    • 汇编语言不是高级语言。
    • @EricPostpischil 是的。但这只是因为汇编和机器代码之间没有任何关系。较新的汇编器也有宏和控制流,例如 while、for 等。C 与 Ruby 相比是什么?
    • 该问题询问高级语言。汇编不是高级语言。因此,它相对于 C 的性能与这个问题无关。这个答案没有解决这个问题。
    • @EricPostpischil 是的,但无论如何它都是我回答的一部分,因为斯大林之于 C 之于 C 之于汇编。它解决了这个问题,因为使用较低级别的语言作为主机没有什么可以更快。 (虽然理论上你可以制作一个比 C 更快的汇编代码的方案代码)
    • @EricPostpischil BTW OP 的最后一句话,重点是:“是否有其他高级或 低级 语言的编译器正在生成比 C 代码更快的代码,我也不知道?”
    猜你喜欢
    • 2021-03-14
    • 2012-03-11
    • 2010-10-11
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多