当前位置: 首页 > 知识库问答 >
问题:

为什么C++代码的执行速度比Java慢?

宗鸿博
2023-03-14

我最近用Java写了一个计算密集型算法,然后把它翻译成C++。令我吃惊的是,C++的执行速度要慢得多。我现在已经编写了一个更短的Java测试程序,以及一个相应的C++程序-参见下面。我的原始代码具有大量的数组访问功能,测试代码也是如此。C++的执行时间要长5.5倍(请参阅每个程序末尾的注释)。

以下1st21条评论后的结论...

    null
    null
Software environment:
    Ubuntu 16.04 (64 bit).
    Netbeans 8.2 / jdk 8u121 (java code executed inside netbeans)
    g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
    Compilation: g++ -o cpp_test cpp_test.cpp

Java代码:

public class JavaTest {
    public static void main(String[] args) {
        final int ARRAY_LENGTH = 100;
        final int FINISH_TRIGGER = 100000000;
        int[] intArray = new int[ARRAY_LENGTH];
        for (int i = 0; i < ARRAY_LENGTH; i++) intArray[i] = 1;
        int i = 0;
        boolean finished = false;
        long loopCount = 0;
        System.out.println("Start");
        long startTime = System.nanoTime();
        while (!finished) {
            loopCount++;
            intArray[i]++;
            if (intArray[i] >= FINISH_TRIGGER) finished = true;
            else if (i <(ARRAY_LENGTH - 1)) i++;
            else i = 0;
        }
        System.out.println("Finish: " + loopCount + " loops; " +
            ((System.nanoTime() - startTime)/1e9) + " secs");
        // 5 executions in range 5.98 - 6.17 secs (each 9999999801 loops)
    }
}

C++代码:

//cpp_test.cpp:
#include <iostream>
#include <sys/time.h>
int main() {
    const int ARRAY_LENGTH = 100;
    const int FINISH_TRIGGER = 100000000;
    int *intArray = new int[ARRAY_LENGTH];
    for (int i = 0; i < ARRAY_LENGTH; i++) intArray[i] = 1;
    int i = 0;
    bool finished = false;
    long long loopCount = 0;
    std::cout << "Start\n";
    timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    long long startTime = (1000000000*ts.tv_sec) + ts.tv_nsec;
    while (!finished) {
        loopCount++;
        intArray[i]++;
        if (intArray[i] >= FINISH_TRIGGER) finished = true;
        else if (i < (ARRAY_LENGTH - 1)) i++;
        else i = 0;
    }
    clock_gettime(CLOCK_REALTIME, &ts);
    double elapsedTime =
        ((1000000000*ts.tv_sec) + ts.tv_nsec - startTime)/1e9;
    std::cout << "Finish: " << loopCount << " loops; ";
    std::cout << elapsedTime << " secs\n";
    // 5 executions in range 33.07 - 33.45 secs (each 9999999801 loops)
}

共有1个答案

梁韬
2023-03-14

我能让C++程序优于Java的唯一一次是在使用分析信息时。这表明运行时信息(Java在默认情况下获得)中存在允许更快执行的内容。

除了一个非常重要的if语句之外,程序中没有太多的内容。也就是说,如果不分析整个程序,很难预测哪个分支是最有可能的。这使我相信这是一个分支错误预测的问题。现代CPU执行指令流水线操作,这允许更高的CPU吞吐量。然而,这需要预测下一个要执行的指令是什么。如果猜测错误,必须清除指令管道,并加载正确的指令(这需要时间)。

在编译时,编译器没有足够的信息来预测哪个分支是最有可能的。CPU也会做一些分支预测,但这通常是沿着loops loop和ifs if(而不是else)的路线。

然而,Java的优点是能够在运行时和编译时使用信息。这允许Java将中间分支标识为最频繁出现的分支,并为管道预测该分支。

 类似资料:
  • 问题内容: 我有一个2 GB的文件(),其中文件中的每一行都是一个单词,就像: 我需要编写一个程序来读取文件中的每个单词并打印单词计数。我使用Java和C 编写它,但结果令人惊讶:Java运行速度是C 的2.3倍。我的代码如下: C ++: 输出: Java: 输出: 在这种情况下,为什么Java比C 快?如何提高C 的性能? 问题答案: 您不是在比较同一件事。Java程序读取行,以换行符开头,而

  • 为什么我的SIMD向量4长度函数比原始向量长度方法慢3倍? SIMD矢量4长度函数: 幼稚的实现: 我用GCC(Ubuntu7.4.0-1Ubuntu1~18.04.1)7.4.0: SSE版本输出: 纯C版本输出:

  • 问题内容: 以下是C 中的一个简单循环。计时器正在使用QueryPerformanceCounter(),并且非常准确。我发现Java占用了C 60%的时间,这不是吗?我在这里做错了什么?即使是严格的别名(此处未包含在代码中)也完全没有帮助… 此C ++的运行时间约为9.5秒。我正在将Intel Compiler 12.1用于主机处理器优化(专门针对我的处理器),并将所有功能都最大化。所以这是最好

  • 问题内容: 我发现这一点的同时解决问题205的项目欧拉。问题如下: 彼得有九个四面(金字塔形)骰子,每个骰子的编号分别为1、2、3、4。科林有六个六边形(立方)骰子,每个骰子的编号为1、2、3、4、5、6。 彼得和科林掷骰子并比较总数:最高的总胜利数。如果总数相等,则结果为平局。 金字塔形皮特击败立方柯林的概率是多少?以0.abcdefg的形式将答案四舍五入到小数点后七个位 我用番石榴写了一个幼稚

  • 问题内容: 没有迅速的方法。该程序必须从某处开始执行。那么快速代码执行的切入点是什么,它是如何确定的? 问题答案: 普通Swift模块中的入口点是模块中名为的文件。是唯一一个允许在顶层具有表达式和语句的文件(模块中的所有其他Swift文件只能包含声明)。 可可触摸使用属性上的实现,而不是一个纪念的入口点文件。可可曾经使用了一个简单的最小文件,但是从Xcode 6.1开始, 它在的实现上使用属性。

  • 在运行一个数字积分器时,我注意到根据我在字典中提取字段值的方式,速度有明显的不同 在我的系统上,我注意到以下差异(使用 iPython) 相比于 这似乎是一个很小的差异,但是对于某些阵列来说,这种差异甚至更大。是什么导致了这种行为,有什么方法可以改变我对< code>get()函数的使用吗?