理解C++相对于其他语言的性能优势[已关闭]

mcvgt66p  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(129)

已关闭,此问题为opinion-based。目前不接受答复。
**想改善这个问题吗?**更新问题,以便editing this post可以用事实和引用来回答。

2天前关闭。
截至2天前,社区正在审查是否重新讨论此问题。
Improve this question
为什么C在执行速度方面优于Java和Python?造成这种性能差异的因素是什么?我进行了一些测试,我想了解这些结果背后的原因。
背景:我是一名计算机科学专业的学生,我一直在探索不同的编程语言,以了解它们的性能特点。在我的实验中,我注意到C
在执行速度方面始终优于Java和Python。然而,我想更深入地了解导致这种性能差异的潜在因素。
硬件和编译详细信息:为了确保公平的比较,我在三种语言中使用相同的逻辑和数据集执行了相同的算法。实验在具有Intel Core i7处理器(8核)和16 GB RAM的系统上进行。
对于C++代码,我使用GCC 10.2.0,并带有以下编译标志:

g++ -O3 -march=native -mtune=native -std=c++17 -o program program.cpp

使用OpenJDK 11.0.1执行Java,命令如下:

java -Xmx8G -Xms8G Program

使用Python 3.9.0执行Python代码,如下所示:

python3 program.py

问题描述:我实现了一个复杂的算法,涉及重要的计算任务,如矩阵运算和数值模拟。该算法旨在有效地解决现实世界中的问题。下面是C++代码的简化版本:

#include <iostream>
#include <chrono>

// ... Algorithm implementation ...

int main() {
    // Measure execution time
    auto start = std::chrono::steady_clock::now();

    // Algorithm execution
    // ...

    auto end = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

    std::cout << "Execution time: " << duration << " ms" << std::endl;

    return 0;
}

我还在Java和Python中实现了相同的算法,具有等效的逻辑和计算。然而,我注意到一个显著的性能差异有利于C++。与Java和Python相比,运行C代码时,相同输入数据的执行时间始终较低。
我知道C
通常是编译的,Java使用虚拟机仿真,Python是解释的。因此,我意识到执行方法和编译器优化可能在这些性能差异中发挥重要作用。但是,我希望更详细地解释观察到的性能差异背后的具体原因。
此外,我考虑了这个建议,并进行了更长时间的测试,在更大的数据集上运行算法,以最大限度地减少Java和Python初始启动成本的影响。尽管如此,C和其他语言之间的性能差异仍然很大。
有人能解释一下为什么C
在这种情况下始终优于Java和Python吗?在Java和Python中,是否有特定的编译器标志或运行时设置可以调整,以提高它们在类似计算任务中的性能?
感谢您的见解和专业知识!

pieyvz9o

pieyvz9o1#

让我以一段题外话开始(也许也是结束--我不确定我会有多雄心勃勃)。

标杆管理难

根据你得到的时间,在我看来,你很可能是在为整个程序的执行计时。不幸的是,这几乎肯定是由将数据写入标准输出所花费的时间所决定的,所以如果(例如)将输出重定向到文件,那么它的运行速度很可能会快得多。取决于测试环境等,这将是相当容易产生相当误导的结果。
举个例子,我猜你是在Windows下计时的,Windows的控制台输出相当慢。当我在Linux下运行Python代码时,我得到了0.108秒的时间--Python比C运行得快。但几乎可以肯定的是,这主要是由于Linux的控制台输出速度比Windows快得多,而与Python或C本身无关。
让我们只计算C++的计算部分,看看我们得到了什么。

// preceding code as you wrote it

int main() {
    int n = 1000;
    using namespace std::chrono; // added

    auto start = high_resolution_clock::now(); // added

    std::vector<int> primeNumbers = generatePrimes(n);

    auto stop = high_resolution_clock::now(); //added

    std::cout << "First " << n << " prime numbers: ";
    for (int prime : primeNumbers) {
        std::cout << prime << " ";
    }    
    std::cout << std::endl;

    // added:
    std::cout << "Time: " << duration_cast<microseconds>(stop-start).count() << "us\n";
    return 0;
}

在我的机器上(速度不是特别快),我得到:
时间:394 us
因此,即使程序运行的时间要长得多,但基本上所有这些都被显示输出所消耗。实际的计算只花了0.394毫秒--只是整个时间的一小部分。
但是写出结果仍然很重要--如果你不写出结果,编译器通常会检测到你没有使用它,根本就不计算它。
即使加上我所做的补充,时间可能很容易不太完美,说得委婉些。特别是,现代CPU可以无序地执行指令,所以计算可能在我抓住开始时间之前开始和/或在我抓住停止时间之后完成。这也可以避免,但它更困难(在这种情况下,快速计算它应该花多少时间,我猜时钟产生的至少是合理准确的)。但是你通常必须至少从一个像样的猜测开始,如果你的结果是由一个重要的因素,你可能需要更仔细地看事情。

C++与Python

C++和Python之间的最大区别在于动态和动态。静态类型在Python中,变量可以附加到任何类型的值,并且该类型可以在其生命周期中更改。例如,我们可以完全合法地拥有某个变量a,它在某个时间保存一个数字,在另一个时间保存字符串。

a = 3
print(a, type(a))
a = "three"
print(a, type(a))

结果:

3 <class 'int'>
three <class 'str'>

正因为如此,当你在Python中执行几乎任何操作时,代码都必须(在运行时)查找每个变量的类型,以确定正在执行的实际操作,因为它执行的操作取决于它们的类型。
在C中,类型大多数是静态的(尽管你可以使用std::any<>std::variant<>来获得动态类型的有限模仿)。当然,代码中的类型完全是静态的。这意味着编译器已经在 * 编译 * 时查找了要应用于操作数的操作,因此它根本不会影响执行时间。
在本例中,您正在执行大量的简单操作。在Python代码中,很可能大部分时间都花在查找操作数类型上,并找出适合这些操作数的操作,只有一小部分时间用于实际执行操作本身。
现在,一个足够聪明的Python实现确实可以经常(甚至可能通常)提前推断类型。当我执行类似a = 7的代码时,a显然是一个int。基于后来应用于a的操作,它通常可以跟踪a在其整个生命周期中将具有什么类型,并专门为该类型生成代码。
因此,大部分的速度损失并不一定是Python作为一种语言所固有的,只是对于它的最常见的实现。至少从理论上讲,可以编写一个实现,它可能提供更接近C
的性能(特别是对于像您编写的代码,其中没有任何东西依赖于用户输入)。
然而,我的猜测是,一般的Pythonista对这样做的React通常是:“如果你想要C++,你知道在哪里可以找到它。”至少对于他们中的绝大多数人来说,有更重要的方法来花费时间和精力(这将是大量的时间和精力)。

相关问题