Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
性能优化:C++;vs Java未按预期执行 我编写了两个程序,用于实现矩阵乘法的简单算法,一个是C++,一个是java。与我的预期相反,java程序比C++程序运行速度快2.5X。我是C++初学者,希望能在C++程序中改变什么,使它运行得更快。_Java_C++_Performance_Optimization - Fatal编程技术网

性能优化:C++;vs Java未按预期执行 我编写了两个程序,用于实现矩阵乘法的简单算法,一个是C++,一个是java。与我的预期相反,java程序比C++程序运行速度快2.5X。我是C++初学者,希望能在C++程序中改变什么,使它运行得更快。

性能优化:C++;vs Java未按预期执行 我编写了两个程序,用于实现矩阵乘法的简单算法,一个是C++,一个是java。与我的预期相反,java程序比C++程序运行速度快2.5X。我是C++初学者,希望能在C++程序中改变什么,使它运行得更快。,java,c++,performance,optimization,Java,C++,Performance,Optimization,我的程序从这篇博文中借用代码和数据 以下是我正在使用的当前编译标志: g++ -O3 main.cc javac Main.java 以下是当前的编译器/运行时版本: $ g++ --version g++.exe (GCC) 4.8.1 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO

我的程序从这篇博文中借用代码和数据

以下是我正在使用的当前编译标志:

g++ -O3 main.cc    

javac Main.java
以下是当前的编译器/运行时版本:

$ g++ --version
g++.exe (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
我的电脑是~2012年的core i3笔记本电脑,运行windows和MinGW。以下是当前的性能结果:

$ time ./a.exe < ../Testing/2000.in
507584919
real    0m36.469s
user    0m0.031s
sys     0m0.030s

$ time java Main < ../Testing/2000.in
507584919
real    0m14.299s
user    0m0.031s
sys     0m0.015s
$time./a.exe<../Testing/2000.in
507584919
实数0m36.469s
用户0m0.031s
系统0m0.030s
$time java Main<../Testing/2000.in
507584919
真实0m14.299s
用户0m0.031s
系统0m0.015s

这里是C++程序:

#include <iostream>
#include <cstdio>
using namespace std;

int *A;
int *B;
int height;
int width;

int * matMult(int A[], int B[]) {
        int * C = new int[height*width];
        int n = height;
        for (int i = 0; i < n; i++) {
            for (int k = 0; k < n; k++) {
                for (int j = 0; j < n; j++) {
                    C[width*i+j]+=A[width*i+k] * B[width*k+j];
                }
            }
        }
        return C;
}

int main() {
  std::ios::sync_with_stdio(false);
  cin >> height;
  cin >> width;
  A = new int[width*height];
  B = new int[width*height];
  for (int i = 0; i < width*height; i++) {
    cin >> A[i];
  }

  for (int i = 0; i < width*height; i++) {
    cin >> B[i];
  }

  int *result = matMult(A,B);
  cout << result[2];
}
#包括
#包括
使用名称空间std;
int*A;
int*B;
内部高度;
整数宽度;
int*matMult(int A[],int B[]{
int*C=新int[高度*宽度];
int n=高度;
对于(int i=0;i>高度;
cin>>宽度;
A=新整数[宽度*高度];
B=新整数[宽度*高度];
对于(int i=0;i>A[i];
}
对于(int i=0;i>B[i];
}
int*result=matMult(A,B);

cout我无法分析java执行,因为它创建了一个临时的可执行模块,该模块在“使用”后消失。但是,我假设它确实执行SSE指令以获得该速度[或者它展开循环,如果禁用SSE指令,clang++会这样做]

但是使用g++(4.9.2)和clang++编译时,我可以清楚地看到,clang优化了循环以使用SSE指令,而gcc没有。因此,生成的代码的速度要慢4倍。更改代码以便在每个维度中使用2000的常量值[因此编译器“知道”高度和宽度的维度],gcc编译器生成的代码大约需要8秒(在我的机器上!),相比之下,使用“变量”值生成的代码需要27秒(在这里,铿锵编译的代码也稍微快一点,但我可以说是在噪音范围内)

<> P.结论:编译器的质量/聪明将对紧环的性能产生很大的影响。代码越复杂和变化,C++解决方案越可能产生更好的代码,简单而易于编译的问题在java代码中可能会更好(通常是,但不能保证)。例如,我希望java编译器使用评测来确定循环的数量

编辑:

time
的结果可用于确定读取文件是否花费了很长时间,但您需要某种分析工具来确定实际输入是否占用了大量CPU时间等

java引擎使用一个“即时编译器”,它使用剖析来确定特定代码片段命中的次数(你也可以为C++做这件事,而大项目经常这样做!)它允许它在一个循环中展开循环,或者在运行时确定循环的次数。因为这个代码执行2000×2000×2000循环,而C++编译器在知道这些值的大小告诉我们java运行时实际上没有做得更好(至少不是最初)时,实际上做得更好。,只是随着时间的推移,它成功地提高了性能

不幸的是,由于java运行时的工作方式,它没有留下二进制代码,因此我无法真正分析它的功能

这里的关键是,你所做的实际操作很简单,逻辑很简单,只是很多,而且你使用的是简单的实现。java和C++都会从手动展开循环中受益,例如:

< P> <强> C++默认的速度不比java < /强>

C++作为一种语言是很快的,但是一旦你将库合并到混合中,你就注定了这些库的速度

该标准很难为性能和周期而构建。标准库的编写考虑了设计和正确性

C++为您提供了优化的机会!
如果您对标准库的性能不满意,您可以而且应该使用自己的优化版本

例如,标准C++ ++对象在设计(流、区域、刻面、内部缓冲区)时很漂亮,但是这使得它们在性能上很差。 如果您是为Windows操作系统编写的,则可以使用
ReadFile
WriteConsole
作为IO机制。

如果您切换到这些函数而不是标准库,那么您的程序的性能会比Java好几个数量级。

您是否实际测量过这两种情况下加载文件的时间?刚刚测量过。将发布上述结果。两个程序看起来都不是特别“快”在java代码中,使用正则表达式似乎特别有助于使它慢下来。一般来说,我认为MICOCOBITICONDEX是一个坏主意。@ MatsPetersson,我同意。C++中的缓冲区值读很可能比java中的缓冲线读慢。这看起来像是一个愚蠢的问题,但是你总是检查C++ P吗?首先,java程序,当java程序运行时,它可以把输入文件放在缓存中。Mats,谢谢你的回答。我做了你建议的修改——HalcDead 2000的高度和宽度。在这种情况下C++在我的计算机上运行8秒,比原来快4倍。
import java.util.*;
import java.io.*;

public class Main {

    static int[] A;
    static int[] B;
    static int height;
    static int width;

public static void main(String[] args) {
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        height = Integer.parseInt(reader.readLine());
        width = Integer.parseInt(reader.readLine());
        A=new int[width*height];
        B=new int[width*height];
        int index = 0;

        String thisLine;
        while ((thisLine = reader.readLine()) != null) {
            if (thisLine.trim().equals("")) {
                break;
            } else {
                String[] lineArray = thisLine.split("\t");
                for (String number : lineArray) {
                    A[index] = Integer.parseInt(number);
                    index++;
                }
            }
        }

        index = 0;
        while ((thisLine = reader.readLine()) != null) {
            if (thisLine.trim().equals("")) {
                break;
            } else {
                String[] lineArray = thisLine.split("\t");
                for (String number : lineArray) {
                    B[index] = Integer.parseInt(number);
                    index++;
                }
            }
        }

        int[] result = matMult(A,B);
        System.out.println(result[2]);

        reader.close();


    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static int[] matMult(int[] A, int[] B) {
        int[] C = new int[height*width];
        int n = height;
        for (int i = 0; i < n; i++) {
            for (int k = 0; k < n; k++) {
                for (int j = 0; j < n; j++) {
                    C[width*i+j]+=A[width*i+k] * B[width*k+j];
                }
            }
        }
        return C;
    }
}
$ time ./IOonly.exe < ../Testing/2000.in
7
944
real    0m8.158s
user    0m0.000s
sys     0m0.046s

$ time java IOOnly < ../Testing/2000.in
7
944
real    0m1.461s
user    0m0.000s
sys     0m0.047s