【问题标题】:Languages faster than C++ [closed]比 C++ 更快的语言 [关闭]
【发布时间】:2010-10-11 06:10:27
【问题描述】:

据说 Blitz++ 提供了接近 Fortran 的性能

对于同等任务,Fortran 是否真的比常规 C++ 更快?

其他具有出色运行时性能的 HL 语言呢?我听说过一些语言在某些任务上超过了 C++……Objective Caml、Java、D……

我猜 GC 可以使很多代码更快,因为它消除了围绕堆栈进行过多复制的需要? (假设代码不是为了性能而编写的)

我是出于好奇而问的——我一直认为 C++ 几乎是无与伦比的,除非有专家 ASM 编码。

【问题讨论】:

  • (OT) 这家伙语言很快:youtube.com/watch?v=NeK5ZjtpO-M
  • 这里是各种语言在各种硬件上的各种任务中的各种实现的比较:shootout.alioth.debian.org
  • 可悲的是,它是封闭的禁食语言是汇编代码,没有编译器可以击败理解它的人类程序员。

标签: c++ programming-languages performance


【解决方案1】:

这在很大程度上取决于编译器、程序员、它是否具有 gc 并且可能变化太大。如果它被直接编译成机器代码,那么在大多数情况下,它的性能应该比解释的要好,但是在你获得 asm 速度之前,可能需要进行有限的优化。

如果有人说 fortran 稍微快一点,你会用那种方式编写一个新项目吗?

【讨论】:

  • 不,当然不是 :) 我更好奇的是什么可以让它更快——也许它的表达力较低,所以它可以做出更多的假设/优化,诸如此类。我不知道fortran。
【解决方案2】:

通常是算法而不是语言决定了你最终的表现。

在这个范围内,优化编译器通常可以生成比大多数汇编编码器更好的代码。

Premature optimisation is the root of all evil

这可能是每个人都可以模仿的“常识”,但我认为这可能是因为它是正确的。我等待相反的具体证据。

【讨论】:

    【解决方案3】:

    对于纯数字代码,Fortran 比 C++ 更快,而且几乎总是比 C++ 更好。 Fortran 速度更快的原因有很多。它是最古老的编译语言(在优化编译器方面有很多知识)。它仍然是数值计算的语言,因此许多编译器供应商以销售优化编译器为生。还有其他更多的技术原因。 Fortran(至少是 Fortran77)没有指针,因此不存在困扰该域中 C/C++ 语言的别名问题。许多高性能库仍然使用 Fortran 编码,历史悠久(> 30 年)。 C 和 C++ 都没有好的数组结构(C 级别太低,C++ 的数组库与地球上的编译器一样多,它们彼此不兼容,因此无法形成经过良好测试的快速代码池)。

    【讨论】:

    • 为了完整起见,f90 有指针,但它们与 C 和亲戚中的指针完全不同(谢谢)。除此之外,你提出了一些好的观点。 +向上
    • 为什么在shootout.alioth.debian.org/gp4/…的所有基准测试中,Fortran都比 C++ 快(在容错范围内)
    • 我并没有说 fortran 比 C 快(这个断言无论如何都没有意义),我说对于数字代码,fortran 比 C 更快更好,特别是依赖数组的那个:更快和更好的语法。顺便说一句,shoutout 是一个相对较差的基准。
    • 枪战页面上的 Fortran 源代码很糟糕。对于数字,Fortran 比 C/C++ 更快、更易读、更易移植和可维护,简单明了。
    • @sixlettervariables:代码枪战页面已提交。如果您认为代码很糟糕,请随时提交更快的代码。如果你看细节,Fortran 在所有提交的任务中都相当于 C++,除了 k-核苷酸,只有一个提交,这很糟糕。如果您可以为该任务编写一个快速版本,那应该可以解决比较问题。
    【解决方案4】:

    由于语言实现数组的方式不同,FORTAN 通常比 C++ 更快地处理数组 - FORTRAN 不允许数组元素的别名,而 C++ 允许。这使得 FORTRAN 编译器的工作更容易。此外,FORTRAN 有许多非常成熟的数学库,这些库已经研究了近 50 年——C++ 并没有出现那么久!

    【讨论】:

    • Fortran EQUIVALENCE 语句可以为数组元素创建别名。
    • 是的,但是编译器会知道别名。对于 C++(和 C),编译器可能无法推断出许多别名。
    【解决方案5】:

    这完全取决于编译器,例如 Stalin Scheme 编译器,它几乎胜过 Debian 微型基准测试套件中的所有语言,但他们是否提到了编译时间?

    不,我怀疑(我以前没有使用过斯大林)编译基准测试(我在最大努力水平下进行所有优化)除了最小的代码片段之外的任何东西都需要很长时间。

    【讨论】:

      【解决方案6】:

      编译语言的性能是一个无用的概念:重要的是编译器的质量,即它能够应用哪些优化。例如,通常(但并非总是)英特尔 C++ 编译器生成的代码性能优于 g++。那么如何衡量 C++ 的性能呢?

      语言语义的用处在于程序员让编译器创建最佳输出是多么容易。例如,并行化 Fortran 代码通常比 C 代码更容易,这就是为什么 Fortran 仍然大量用于高性能计算(例如气候模拟)的原因。


      正如问题和一些答案提到的汇编程序:这里也是如此,它只是另一种编译语言,因此本质上并不“更快”。汇编程序和其他语言之间的区别在于,程序员(理想情况下对程序有绝对的了解)负责所有优化,而不是将其中的一些优化委托给“愚蠢的”编译器。

      例如,汇编器中的函数调用可以使用寄存器来传递参数并且不需要创建不必要的堆栈帧,但是一个好的编译器也可以做到这一点(想想内联或快速调用)。使用汇编程序的缺点是性能更好的算法更难实现(想想线性搜索与二进制搜索、哈希表查找......)。

      【讨论】:

      • 嗯.. 考虑到该语言的速度在任何编译器下都是最好的。我不在这里分裂头发。并行化 Fortran 代码更容易吗?有趣 :) 所以 fortran 与 FP 有一些共同点。
      【解决方案7】:

      Blitz++ 与之竞争的不是 Fortran 语言,而是 Fortran 数学库中的几个世纪的工作。在某种程度上,该语言有所帮助:一种较旧的语言有更多的时间来优化编译器(而且,让我们面对现实吧,C++ 是最复杂的语言之一)。另一方面,像 Blitz++uBLAS 这样的高级 C++ 库允许您比相对低级的 Fortran 代码更清楚地说明您的意图,并允许全新的编译时优化类。

      但是,始终有效地使用任何库都需要开发人员熟悉该语言、库数学。您通常可以通过改进这三个中的任何一个来获得更快的代码...

      【讨论】:

        【解决方案8】:

        如果代码不是为了性能而编写的那么C# is faster than C++

        必要的免责声明:所有基准都是邪恶的。

        这是in favour of C++ 的基准测试。

        以上两个链接表明我们可以找到 C++ 比 C# 快的情况,反之亦然。

        【讨论】:

        • 您链接的文章似乎只分析了系统的内存性能,而不是程序的速度。虽然看起来代码测量时间,但我实际上找不到任何记录时间的参考。此外,这也带来了其他领域,例如硬盘访问。
        • 嗯,第一种情况是一个相当特殊的情况,它在 C++ 中的表现非常糟糕,主要有两个原因。像你一样从中得出一般性结论(“如果代码不是为了性能而编写的,那么 C# 比 C++ 更快”)恕我直言是误导甚至是错误的。
        • @Grant Peters:它分析了时间和内存,例如,尝试从上面的链接中单击“分析托管代码”。上述链接的说明见stackoverflow.com/questions/385297/…
        • @Konrad Rudolph:很明显,我什至一开始都没有包含免责声明。我觉得在不指定应用程序域的情况下谈论快速语言是荒谬的。
        【解决方案9】:

        c++ 的特点是它非常接近硬件级别。事实上,您可以在硬件级别进行编程(通过汇编块)。一般来说,c++ 编译器在优化方面做得很好(为了获得巨大的速度提升,启用“链接时间代码生成”以允许在不同的 cpp 文件之间内联函数),但如果您了解硬件并拥有专有技术,您可以在汇编中编写一些运行速度更快的函数(尽管有时,您无法击败编译器)。

        您还可以实现自己的内存管理器(这是许多其他高级语言所不允许的),因此您可以为您的特定任务自定义它们(也许大多数分配将是 32 字节或更少,那么您就可以拥有一个巨大的 32 字节缓冲区列表,您可以在 O(1) 时间内分配/释放这些缓冲区)。我相信 c++ 可以击败任何其他语言,只要您完全了解编译器和您正在使用的硬件。其中大部分归结为您使用的算法比其他任何东西都多。

        【讨论】:

        • > 实际上,您可以在硬件级别(通过汇编块)进行编程,而该代码是... ASM 而不是 C++。老实说,如果你正在修改 C++ 使其看起来与预期的完全不同,并注入其他技术,那么你对这种语言并不是很诚实。
        【解决方案10】:

        C# 比 C++ 快得多 - 在 C# 中,我可以用我编写 C++ 所需的十分之一时间编写 XML 解析器和数据处理器。

        哦,你是说执行速度吗?

        即便如此,如果从编写第一行代码到第一次执行代码结束这段时间,C# 仍然可能比 C++ 快。

        This is a very interesting article 关于将 C++ 程序转换为 C# 以及使 C++ 比 C# 更快所需的努力。

        所以,如果考虑到开发速度,几乎任何东西都胜过 C++。

        好的,解决 OP 的仅运行时性能要求:决定运行时性能的不是语言,而是语言的实现。我可以编写一个 C++ 编译器来生成可以想象的最慢的代码,但它仍然是 C++。理论上也可以为 Java 编写针对 IA32 指令而不是 Java VM 字节码的编译器,从而提高运行时速度。

        您的代码的性能将取决于语言的优势和代码的要求之间的契合度。例如,由于 C++ 内存分配策略过于笼统,一个执行大量内存分配/释放的程序在幼稚的 C++ 程序(即使用默认内存分配器)中表现不佳,而 C# 的基于 GC 的分配器可以执行得更好(因为上面的链接显示)。字符串操作在 C++ 中很慢,但在 php、perl 等语言中却很快。

        【讨论】:

        • 我对 C++ 非常熟悉,可以以与使用 C# 或 python3 大致相同的速度编写代码。只需要 10 年的经验。
        • ...这意味着你所说的整整10年都不是真的:)
        【解决方案11】:

        fortran 是否比 c++ 更快是一个讨论问题。有人说是,有人说不是;我不会进入那个。这取决于编译器、运行它的架构、算法的实现……等等。

        fortran确实有优于 C 的一大优势是您实现这些算法所需的时间。这使得它非常适合任何类型的数值计算。我将仅说明与 C 相比的一些明显优势:

        • 基于 1 的数组索引(在实现更大的模型时非常有用,您不必考虑它,只需 FORmula TRANslate
        • 有一个幂运算符 (**)(天哪,谁的想法是幂函数可以?而不是运算符?!
        • 它有,我会说是对当前市场上所有语言的多维数组的最佳支持(而且似乎不会这么快改变)-A(1,2) 就像在数学中一样
        • 更不用说避免循环 - A=B*C 将数组相乘(几乎类似于 matlab 语法,编译速度
        • 它具有语言中内置的并行功能(请查看该标准的新标准)
        • 很容易与 C、python 等语言连接,因此您可以在 fortran 中进行繁重的计算,同时 .. 无论如何 ... 使用您选择的语言,如果您愿意的话
        • 完全向后兼容(因为整个 F77 是 F90 的子集),因此您可以使用整个世纪的编码
        • 非常便携(这可能不适用于某些编译器扩展,但总的来说它就像一个魅力)
        • 以问题为导向的解决社区(因为 fortran 用户通常不是 cs,而是数学、物理、工程师......没有编程,而是解决问题的经验,他们对您的问题的了解可能非常丰富有帮助)

        我现在想不出其他任何事情,所以必须这样做。

        【讨论】:

        • 基于 1 的数组索引既是福也是祸。无论我坚持使用哪种语言,无论采用哪种约定,对于手头的问题,似乎相反的语言更自然....
        • 是的,从 1 开始并不比从 0 开始好。我看不出它对任何模型有何帮助 - 根据字段,索引从 0 或 1(或其他)开始。在信号处理中,从 0 开始索引是很常见的。
        • 在“经典”工程领域(机械、地理、海洋、航空 ....)中使用基于 1 的索引,没有两难选择。数学家也使用从 1 开始的。我还发现基于 1 的逻辑更合乎逻辑,如果数组的一个元素长度 = 1,如果你在第 5 个元素上,则 =5 ......那是一件事情。
        • 由于这些领域的所有材料(书籍、文章……等等)都是使用该索引编写的,因此一直考虑索引翻译可能会非常(极度)疲劳。
        • C 缺少指数运算符,因为大多数 CPU 没有指数指令。据我了解,在 C 语言中,运算符保留用于大多数硬件将在恒定时间内执行的功能,最多只需要几条指令。
        【解决方案12】:

        在实际应用中,D 有时可能比 C++ 更快,这主要是因为垃圾收集的存在有助于避免使用智能指针时 RAII 和引用计数的开销。对于分配大量具有重要生命周期的小对象的程序,垃圾收集可能比 C++ 风格的内存管理更快。此外,D 的内置数组允许编译器在某些情况下执行比编译器不理解的 C++ 的 STL 向量更好的优化。此外,D2 支持不可变数据和纯函数注释,最近的 DMD2 版本在此基础上进行了优化。 D 的创造者 Walter Bright 用 D 和 C++ 编写了一个 JavaScript 解释器,据他说,D 版本更快。

        【讨论】:

        • 垃圾收集逻辑不应该适用于Java和C#等其他抓取收集语言吗?
        • 是的,这些语言有时也可以比 C++ 更快,但 D 更常见,因为它在其他地方的开销更少。
        • 刀片怎么样?是否曾经以 blitz 或 fortran 为基准?
        • 这是一个利用 D 的编译时编程特性来生成据称接近最优的 X86 浮点代码的库。我不知道它现在的状态如何,但它在几年前引起了很多人的兴趣。
        • 今天 BLADE 的性能应该大大优于 LDC 编译代码,因为 LDC 可以矢量化和使用具有典型 LLVM 优化的 SSE/AVX
        【解决方案13】:

        比 C++ 做得更好主要是为了让编译器理解程序员的意思。这方面的一个例子可能是任何语言的编译器推断代码区域独立于其输入并且仅在编译时计算结果值的实例。

        另一个例子是 C# 如何生成一些非常高性能的代码,这仅仅是因为编译器知道特定的咒语“意味着”什么,并且可以巧妙地使用产生最高性能的实现,其中将同一程序音译成 C++ 会导致不必要的分配/删除循环(被模板隐藏),因为编译器正在处理一般情况而不是这段代码给出的特定情况。

        最后一个例子可能是 C 的 Brook/Cuda 改编版,专为不再那么奇特的奇异硬件而设计。该语言支持映射到正在编译的非冯诺依曼硬件的确切原语(内核函数)。

        【讨论】:

          【解决方案14】:

          这就是您使用托管浏览器的原因吗?因为它更快。或托管操作系统,因为它更快。不,等一下,它是 SQL 数据库。等等,它一定是你在玩的游戏。停下,肯定有一段数字代码 Java和Csharp坦白用没用。顺便说一句,你必须检查你的虚拟机是用什么写的来渣根语言并说它很慢。

          真是个误解,但请给我看一个快速托管的应用程序,这样我们都可以开怀大笑。 VS?开发办公室?

          【讨论】:

            【解决方案15】:

            当您加载此页面时,您必须使用一些奇怪的托管 XML 解析器。 :)

            我们不断地分析代码并且获得一致的收益(这不是天真的 C++,它只是带有嘘声的现代 C++)。它始终如一地将任何 CLR 实现铺平了至少 2 倍,通常是 5 倍或更多。比 Java 时代快 20 倍的时代要好一些,但您仍然可以找到好的实例,并简单地消除所有 System.Object 膨胀,并将其明显击败。

            托管开发人员没有得到的一件事是硬件架构反对任何 VM 和对象根方法的扩展。你必须亲眼看到它才能相信它,坚持住,启动浏览器并转到像 Silverlight 这样的“瘦”虚拟机。你会被它的速度和 CPU 消耗量吓到。

            二,任何性能的数据库应用程序,是托管数据库与本机数据库。

            【讨论】:

              【解决方案16】:

              啊...这个老问题 - 哪个编译器可以生成更快的代码?

              1. 仅在实际花费大量时间在调用堆栈底部的代码中才重要,即不包含函数调用的热点,例如矩阵求逆等。

              2. (由 1 暗示)它只在编译器实际看到的代码中很重要。如果您的程序计数器将所有时间都花在您不构建的第三方库中,那没关系。

              3. 在真正重要的代码中,一切都取决于哪个编译器可以制作更好的 ASM,而这在很大程度上取决于源代码编写的聪明或愚蠢。

              有了所有这些变量,很难区分好的编译器。

              但是,如前所述,如果您有很多 Fortran 代码要编译,请不要重新编写。

              【讨论】:

                猜你喜欢
                • 2021-03-14
                • 1970-01-01
                • 2015-12-24
                • 2019-04-30
                • 1970-01-01
                • 2010-10-22
                • 2012-03-11
                • 2015-06-22
                • 1970-01-01
                相关资源
                最近更新 更多