性能问题:Java 与 C++

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24914525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:35:54  来源:igfitidea点击:

Performance issue: Java vs C++

javac++performancealgorithm

提问by realUser404

I have always heard that C++ was way more efficient than Java (and that is why most games are developed in C++).

我一直听说 C++ 比 Java 更有效率(这就是为什么大多数游戏都是用 C++ 开发的)。

I wrote a small algorithm to solve the "Eight queens puzzle" in both Java and C++, using the exact same algorithm, and then started to raise the number or squares. When reaching checkboards of 20*20 or even 22*22, it appears Java is much more effective (3 seconds vs 66 seconds for C++).

我写了一个小算法来解决 Java 和 C++ 中的“八皇后之谜”,使用完全相同的算法,然后开始增加数字或平方。当达到 20*20 甚至 22*22 的棋盘格时,Java 似乎更有效(3 秒对 C++ 66 秒)。

I have no idea why, but I am pretty beginning with C++, so it is possible I made some huge performance mistakes, so I will gladly accept any information that would help me understand what is happening.

我不知道为什么,但我刚开始使用 C++,所以我可能犯了一些巨大的性能错误,所以我很乐意接受任何有助于我理解正在发生的事情的信息。

Below is the code I use in Java:

下面是我在Java中使用的代码:

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class HuitDames {

    /**
     * La liste des coordnnées des dames.
     */
    private static List<Point> positions = new ArrayList<>();

    /**
     * Largeur de la grille.
     */
    private static final int LARGEUR_GRILLE = 22;


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int i = 1;
        placerDame(i);
        for (Point point : positions) {
            System.out.println("(" + point.x + "; " + point.y + ")");
        }
    }

    /**
     * Place une dame et return true si la position est bonne.
     * @param i le numéro de la dame.
     * @return si la position est bonne.
     */
    private static boolean placerDame(int i) {

        boolean bonnePosition = false;
        for (int j = 1; j <= LARGEUR_GRILLE && bonnePosition == false; j++) {
            Point emplacement = new Point(i, j);
            positions.add(emplacement);
            if (verifierPrise(emplacement) && (i == LARGEUR_GRILLE || placerDame(i + 1))) {
                bonnePosition = true;
            }
            else {
                positions.remove(i - 1);
            }
        }

        return bonnePosition;
    }

    /**
     * Vérifie que la nouvelle position n'est pas en prise avec une position déjà présente.
     * @param position la position de la nouvelle dame.
     * @return Si la position convient par rapport aux positions des autres dames.
     */
    private static boolean verifierPrise(Point position) {
        boolean nonPrise = true;
        for (Point point : positions) {
            if (!point.equals(position)) {
                // Cas où sur la même colonne.
                if (position.y == point.y) {
                    nonPrise = false;
                }
                // Cas où sur même diagonale.
                if (Math.abs(position.y - point.y) == Math.abs(position.x - point.x)) {
                    nonPrise = false;
                }
            }
        }

        return nonPrise;
    }
}

And below is the code in C++:

下面是 C++ 中的代码:

#include <iostream>
#include <list>
#include <math.h>
#include <stdlib.h>

using namespace std;


// Class to represent points.
class Point {

    private:
        double xval, yval;

    public:
        // Constructor uses default arguments to allow calling with zero, one,
        // or two values.
        Point(double x = 0.0, double y = 0.0) {
                xval = x;
                yval = y;
        }

        // Extractors.
        double x() { return xval; }
        double y() { return yval; }
};

#define LARGEUR_GRILLE 22
list<Point> positions;


bool verifierNonPrise(Point emplacement) {
    bool nonPrise = true;
    for (list<Point>::iterator it = positions.begin(); it!= positions.end(); it++) {
        if (it->x() != emplacement.x()) {
            if (it->y() == emplacement.y()) {
                nonPrise = false;
            }
            if (abs(it->y() - emplacement.y()) == abs(it->x() - emplacement.x())) {
                nonPrise = false;
            }
        }
    }

    return nonPrise;
}

bool placerDame(int i) {
    bool bonnePosition = false;
    for (int j = 1; j <= LARGEUR_GRILLE && !bonnePosition; j++) {
        Point emplacement(i,j);
        positions.push_back(emplacement);
        if (verifierNonPrise(emplacement) && (i == LARGEUR_GRILLE || placerDame(i + 1))) {
            bonnePosition = true;
        }
        else {
            positions.pop_back();
        }
    }

    return bonnePosition;
}

int main()
{
    int i = 1;
    placerDame(i);
    for (list<Point>::iterator it = positions.begin(); it!= positions.end(); it++) {
        cout << "(" << it->x() << "; " << it->y() << ")" << endl;
    }
    return 0;
}

采纳答案by Brian

std::listin C++ is a linked list, whereas java.util.ArrayListis an array. Try replacing std::listby std::vector. Also, be sure to compile with optimization turned on.

std::list在 C++ 中是一个链表,而在 C++ 中java.util.ArrayList是一个数组。尝试替换std::liststd::vector. 另外,请确保在打开优化的情况下进行编译。

回答by NetVipeC

Test this version, updated using C++11 features. Tested in GCC 4.9.0 with -std=c++11. Tested on Celeron 1.6 GHz, 512 MB RAM.

测试此版本,使用 C++11 功能更新。在 GCC 4.9.0 中使用-std=c++11. 在赛扬 1.6 GHz、512 MB RAM 上测试。

Times in my PC:
Original: Duration (milliseconds): 12658
First Version: Duration (milliseconds): 3616
Optimized Version: Duration (milliseconds): 1745

我的 PC 中的时间
原始:持续时间(毫秒):12658
第一个版本:持续时间(毫秒):3616
优化版本:持续时间(毫秒):1745

Changes are:

变化是:

  • Using vectorinstead of listBenchmark, and Words from Stroustrup.
  • Using const whatever we can, the compiler is able to optimize much more if it known that the value don't change.
  • Using std::pair instead of Point.
  • Using new for-loop with constant iterators.
  • 使用vector代替listBenchmark来自 Stroustrup 的词
  • 尽我们所能使用 const,如果编译器知道该值不会改变,它就能够进行更多优化。
  • 使用 std::pair 而不是 Point。
  • 使用带有常量迭代器的新 for 循环。

Source:

来源:

#include <iostream>
#include <vector>
#include <chrono>
#include <iomanip>

using namespace std;

typedef std::pair<int, int> Point;

#define LARGEUR_GRILLE 22
vector<Point> positions;

bool verifierNonPrise(const Point& emplacement) {
    bool nonPrise = true;
    for (const auto& p : positions) {
        if (p.first != emplacement.first) {
            if (p.second == emplacement.second) {
                nonPrise = false;
            }
            if (abs(p.second - emplacement.second) ==
                abs(p.first - emplacement.first)) {
                nonPrise = false;
            }
        }
    }

    return nonPrise;
}

bool placerDame(int i) {
    bool bonnePosition = false;
    for (int j = 1; j <= LARGEUR_GRILLE && !bonnePosition; j++) {
        Point emplacement(i, j);
        positions.emplace_back(emplacement);
        if (verifierNonPrise(emplacement) &&
            (i == LARGEUR_GRILLE || placerDame(i + 1))) {
            bonnePosition = true;
        } else {
            positions.pop_back();
        }
    }

    return bonnePosition;
}

int main(int argc, char* argv[]) {
    std::chrono::system_clock::time_point begin_time =
        std::chrono::system_clock::now();

    positions.reserve(LARGEUR_GRILLE);

    placerDame(1);
    for (const auto& p : positions) {
        cout << "(" << p.first << "; " << p.second << ")" << endl;
    }

    std::chrono::system_clock::time_point end_time =
        std::chrono::system_clock::now();
    long long elapsed_milliseconds =
        std::chrono::duration_cast<std::chrono::milliseconds>(
            end_time - begin_time).count();
    std::cout << "Duration (milliseconds): " << elapsed_milliseconds
              << std::endl;

    return 0;
}

Some more deep changes.

一些更深刻的变化。

Changes include:

变化包括:

  • Returning as early as possible. As soon as the queen can not be placed.
  • Returning to a simpler Point class.
  • Using find_if algorithm for searching queen placement.
  • 尽早返回。一旦女王不能放置。
  • 回到更简单的 Point 类。
  • 使用 find_if 算法搜索皇后位置。

Source (some recommendation updated):

来源(更新了一些建议):

#include <algorithm>
#include <iostream>
#include <vector>
#include <chrono>
#include <iomanip>

using namespace std;

struct Point {
    int x, y;
};

#define LARGEUR_GRILLE 22
vector<Point> positions;

bool verifierNonPrise(const Point& emplacement) {
    return find_if(positions.cbegin(), positions.cend(), [&emplacement](const Point& p) {
               return (p.x != emplacement.x &&
                       (p.y == emplacement.y ||
                        abs(p.y - emplacement.y) == abs(p.x - emplacement.x)));
           }) == positions.cend();
}

bool placerDame(int i) {
    for (int j = 1; j <= LARGEUR_GRILLE; j++) {
        Point emplacement{i, j};
        positions.push_back(emplacement);
        if (verifierNonPrise(emplacement) &&
            (i == LARGEUR_GRILLE || placerDame(i + 1))) {
            return true;
        } else {
            positions.pop_back();
        }
    }
    return false;
}

int main(int argc, char* argv[]) {
    std::chrono::system_clock::time_point begin_time =
        std::chrono::system_clock::now();

    positions.reserve(LARGEUR_GRILLE);

    placerDame(1);
    for (const auto& p : positions) {
        cout << "(" << p.x << "; " << p.y << ")" << endl;
    }

    std::chrono::system_clock::time_point end_time =
        std::chrono::system_clock::now();
    long long elapsed_milliseconds =
        std::chrono::duration_cast<std::chrono::milliseconds>(
            end_time - begin_time).count();
    std::cout << "Duration (milliseconds): " << elapsed_milliseconds
              << std::endl;

    return 0;
}

回答by Durandal

Comparing a managed, dynamically compiled language like Java to a statically compiled language like C++ is very difficult.

将托管的动态编译语言(如 Java)与静态编译的语言(如 C++)进行比较是非常困难的。

You will always be comparing apples to oranges in a sense, because they are conceptually very different. It starts with the use of the standard libraries (ArrayList vs std::list/vector) that will have potentially wildly different performance characteristics, even your code looks similar in both languages.

在某种意义上,您总是将苹果与橙子进行比较,因为它们在概念上非常不同。它从使用标准库(ArrayList 与 std::list/vector)开始,它们可能具有截然不同的性能特征,即使您的代码在两种语言中看起来也相似。

Then there is the inherent problem with microbenchmarks in Java (short test in Java are always slower because the JITwill observe program flow before it decides what and how it is to be compiled). Same goes for compiler options for C++, even the structureof the source code (independently compiled and linked classes versus single file source) can make a significant difference (because it changes the amount of "insight" the C++ compiler has into the other classes).

然后是 Java 中微基准测试的固有问题(Java 中的简短测试总是较慢,因为JIT在决定编译什么以及如何编译之前会观察程序流)。C++ 的编译器选项也是如此,甚至源代码的结构(独立编译和链接的类与单个文件源)也会产生显着差异(因为它改变了 C++ 编译器对其他类的“洞察”量) .

Next is the general difference in memory management, garbage collection vs manual memory management (smart pointers etc. are still considered manual memory management).

接下来是内存管理的一般区别,垃圾收集与手动内存管理(智能指针等仍被视为手动内存管理)。

Not to mention the general language differences like you need to explicitly declare a method virtual in C++, while in Java everymember method is virtual by default (working out if it's really virtual at runtime is left to the VM).

更不用说一般的语言差异了,比如你需要在 C++ 中显式声明一个虚拟方法,而在 Java 中,默认情况下每个成员方法都是虚拟的(在运行时确定它是否真的是虚拟的由 VM 决定)。

With all those differences there will always be cases where one langauge will have a massive advantage over the other. A simple test with very limited scope (like your test here) says very little about each language as a whole.

由于所有这些差异,总会有一种语言比另一种语言具有巨大优势的情况。一个范围非常有限的简单测试(比如你在这里的测试)对每种语言的整体说明很少。

Another point people often tend to ignore is: How productive can you be with a language - speed isn't everything (look a how sucessful script langages are in some domains, despite being hardly competive when looking onlyat excution speed). Lack of performance canbe crippling, but so can be low productivity.

人们经常忽略的另一点是:您使用一种语言的效率有多高 - 速度不是一切(看看脚本语言在某些领域是多么成功,尽管看执行速度时几乎没有竞争力)。缺乏绩效可能会导致严重后果,但也会导致生产力低下。

回答by Jakub

Also, there is no reason to use float/doouble types for the coordinates.

此外,没有理由为坐标使用 float/double 类型。

You should gain performance if you do not force calling floating point abs library call in your C++

如果您不在 C++ 中强制调用浮点 abs 库调用,您应该会获得性能

Java stores the Point coordinates as integer. The get functions return double, however this is probably easier to optimize away in Java, then in c++.

Java 将点坐标存储为整数。get 函数返回双精度值,但是这可能更容易在 Java 中优化,然后在 C++ 中优化。

回答by Martin York

Updates:

更新:

Changes to C++

对 C++ 的更改

  • As written:
    Compilation Failure
  • Replace math.h => cmath
    27610 milliseconds
  • Add -O3 flag
    4416 milliseconds
  • Replace std::list with std::vector
    2294 milliseconds
  • Replace Point with std::pair
    2384 milliseconds
  • Made verifierNonPrise const correct
    2351 milliseconds
  • Replaced loop in verifierNonPrise with std::find_if
    929 milliseconds
  • Replacing double with int (to make it equiv to Java)
    549 milliseconds
  • 正如所写:
    编译失败
  • 替换 math.h => cmath
    27610 毫秒
  • 添加 -O3 标志
    4416 毫秒
  • 用 std::vector
    2294 毫秒替换 std::list
  • 用 std::pair
    2384 毫秒 替换 Point
  • 使 verifierNonPrise const 正确
    2351 毫秒
  • std::find_if
    929 毫秒替换了 verifierNonPrise 中的循环
  • 用 int 替换 double(使其等同于 Java)
    549 毫秒

Changes to Java

对 Java 的更改

  • As written
    3459 milliseconds
  • Changes verifierNonPriseearly return
    368 milliseconds
  • 如所写
    3459 毫秒
  • 更改verifierNonPrise提前返回
    368 毫秒

Java Vs C++

Java 与 C++

> javac HuitDames.java
> time java HuitDames
real    0m0.368s
user    0m0.436s
sys     0m0.042s    
> g++ -O3 -std=c++11 HuitDames.cpp
> time ./a.out
real    0m0.541s
user    0m0.539s
sys     0m0.002s

Final Code:

最终代码:

#include <iostream>
#include <vector>
#include <cmath>
#include <stdlib.h>
#include <chrono>
#include <algorithm>

using namespace std;

typedef std::pair<int, int>   Point;

#define LARGEUR_GRILLE 22
vector<Point> positions;


bool verifierNonPrise(Point const& emplacement) {
    return std::find_if(positions.begin(), positions.end(), [&emplacement](Point const& val){
        if (val.first != emplacement.first) {
            if ((val.second == emplacement.second) || (abs(val.second - emplacement.second) == abs(val.first - emplacement.first))) {
                return true;
            }
        }
        return false;
    }) == positions.end();
}

bool placerDame(int i) {
    bool bonnePosition = false;

    for (int j = 1; j <= LARGEUR_GRILLE && !bonnePosition; j++) {
        Point emplacement(i,j);
        positions.push_back(emplacement);
        if (verifierNonPrise(emplacement) && (i == LARGEUR_GRILLE || placerDame(i + 1))) {
            bonnePosition = true;
        }
        else {
            positions.pop_back();
        }
    }

    return bonnePosition;
}


int main()
{
    using std::chrono::system_clock;

    system_clock::time_point begin_time = system_clock::now();

    int i = 1;
    placerDame(i);
    for (vector<Point>::iterator it = positions.begin(); it!= positions.end(); it++) {
        cout << "(" << it->first << "; " << it->second << ")" << endl;
    }

    system_clock::time_point end_time = system_clock::now();

    long long elapsed_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - begin_time).count();
    cout << "Duration (milliseconds): "
         << elapsed_milliseconds
         << std::endl;    
}

回答by Amir Saniyan

Java passes objects to methods as references and those references are passed by value, but C++ passes objects by value.

Java 将对象作为引用传递给方法,这些引用是按值传递的,而 C++ 则是按值传递对象。

You should change C++ code to make it same as Java (Pass pointers in C++ intstead of passing objects):

您应该更改 C++ 代码以使其与 Java 相同(在 C++ 中传递指针而不是传递对象):

bool verifierNonPrise(Point* emplacement) // The correct way for passing arguments.

回答by snstrand

C++ can do it in 21 ms (on a old core i7-860) if you use bit maps. For the timing run I commented out the showSoln() call since a graphic display of the chess board takes twice as long as finding the solution.

如果您使用位图,C++ 可以在 21 毫秒内完成(在旧核心 i7-860 上)。对于计时运行,我注释掉了 showSoln() 调用,因为棋盘的图形显示所需的时间是找到解决方案的两倍。

#include <iostream>
#include <iomanip>
#include <fstream>
#include <omp.h>                        //omp_get_wtime() is my favorite time function
using namespace std;

static const unsigned n(22);            //size of board
static_assert(n<32,"use long unsigned for bit masks if n > 32");
static const unsigned mask((1U<<n)-1);  //n wide bitmask with every bit set

void showSoln(unsigned* selCol, unsigned numSoln) {     //show a solution
    cout << "\nsolution " << numSoln << '\n';
    for (unsigned row=0; row<n; ++row) {
        for (unsigned col=0; col<n; ++col)
            cout << (col==selCol[row]? " Q": " .");
        cout << '\n';
    }
}

void main() {
    //for each row bitmasks that show what columns are attacked, 1 bit means attacked
    unsigned ulAttack[n];           //cols attacked from upper left, shift right for next row
    unsigned upAttack[n];           //cols attacked from straight up, same for next row
    unsigned urAttack[n];           //cols attacked from upper right, shift left for next row
    unsigned allAttack[n];          //OR of all attacks on given row
    allAttack[0]= ulAttack[0]= upAttack[0]= urAttack[0]= 0; //no attacks on row 0
    unsigned row= 0;                //the row where now placing a queen 
    unsigned selCol[n];             //for each row the selected column
    unsigned numSoln= 0;            //count of soutions found
    double wtime= omp_get_wtime();
    for (;;) {                                          //loop until find 1st (or all) solutions
        if (allAttack[row]!=mask) {                     //if 'row' has a column not attacked
            unsigned long bit;
            _BitScanForward(&bit,~allAttack[row]);      //find lowest column not attacked
            //note - your compiler may have a different intrinsic for find lowest set bit
            selCol[row]= bit;                           //remember selected column for this row
            unsigned move= 1U<<bit;                     //convert selected column to bitmask
            allAttack[row]|= move;                      //mark column attacked to prevent re-use
            if (row==n-1) {                             //if move in last row have a soln
                ++numSoln;
                showSoln(selCol,numSoln);
                break;                                  //remove this break if want all solutions
            } else {                                    //no solution yet, fill in rows below
                unsigned nrow= row+1;                   //next row
                //from attacks on this row plus 'move' decide attacks on row below
                ulAttack[nrow]= (ulAttack[row] | move) >> 1;
                upAttack[nrow]= (upAttack[row] | move);
                urAttack[nrow]= ((urAttack[row] | move) << 1) & mask;
                allAttack[nrow]= ulAttack[nrow] | upAttack[nrow] | urAttack[nrow];
                row= nrow;                              //go to next row
            }
        } else {                //else move on 'row' is impossible so backtrack
            if (!row)           //if backtrack from row 0 have found all solutions
                break;
            --row;              //try next move in prior row
        }
    }
    wtime= omp_get_wtime() - wtime;
    cout << "numSoln= " << numSoln << '\n';
    cout << "time= " << wtime*1000 << " msec\n";
}

回答by rep_movsd

I may be beating a dead horse here, but simply doing a line by line translation of the Java to C++, not even using const reference parameters or any such thing, you can see the C++ is almost twice as fast as Java. All the "syntactic optimization" emplacing etc. has little effect if any...

我可能在这里打败了一匹死马,但只是将 Java 逐行翻译成 C++,甚至不使用 const 引用参数或任何类似的东西,你可以看到 C++ 几乎是 Java 的两倍。如果有的话,所有的“语法优化”等都几乎没有影响......

rep ~/Documents $ g++ -O3 Queen.cpp
rep ~/Documents $ javac Queen.java 
rep ~/Documents $ time java Queen 
(1; 1)
(2; 3)
(3; 5)
(4; 2)
(5; 4)
(6; 10)
(7; 14)
(8; 17)
(9; 20)
(10; 13)
(11; 19)
(12; 22)
(13; 18)
(14; 8)
(15; 21)
(16; 12)
(17; 9)
(18; 6)
(19; 16)
(20; 7)
(21; 11)
(22; 15)

real    0m4.806s
user    0m4.857s
sys     0m0.067s
rep ~/Documents $ time ./a.out
(1; 1)
(2; 3)
(3; 5)
(4; 2)
(5; 4)
(6; 10)
(7; 14)
(8; 17)
(9; 20)
(10; 13)
(11; 19)
(12; 22)
(13; 18)
(14; 8)
(15; 21)
(16; 12)
(17; 9)
(18; 6)
(19; 16)
(20; 7)
(21; 11)
(22; 15)

real    0m2.131s
user    0m2.113s
sys     0m0.000s
rep ~/Documents $

Queen.java (translated to english)

Queen.java(翻译成英文)

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class Queen {

    private static List<Point> positions = new ArrayList<>();
    private static final int GRID_SIZE = 22;

    public static void main(String[] args) 
    {
        int i = 1;
        placeQueen(i);
        for (Point point : positions) 
        {
            System.out.println("(" + point.x + "; " + point.y + ")");
        }
    }

    private static boolean placeQueen(int i) 
    {
        boolean bIsGoodPos = false;
        for (int j = 1; j <= GRID_SIZE && bIsGoodPos == false; j++) 
        {
            Point emplacement = new Point(i, j);
            positions.add(emplacement);
            if (verifyPos(emplacement) && (i == GRID_SIZE || placeQueen(i + 1))) 
            {
                bIsGoodPos = true;
            }
            else 
            {
                positions.remove(i - 1);
            }
        }

        return bIsGoodPos;
    }

    private static boolean verifyPos(Point position) 
    {
        boolean bIsSafe = true;
        for (Point point : positions) 
        {
            if (!point.equals(position)) 
            {
                if (position.y == point.y) 
                {
                    bIsSafe = false;
                }
                if (Math.abs(position.y - point.y) == Math.abs(position.x - point.x)) 
                {
                    bIsSafe = false;
                }
            }
        }

        return bIsSafe;
    }
}

Queen.cpp

皇后乐队

#include <cmath>
#include <vector>
#include <iostream>

using namespace std;

struct Point
{
    int x, y;
    Point(int ii, int jj):x(ii), y(jj){}
};

vector<Point> positions;
int GRID_SIZE = 22;


bool verifyPos(Point position) 
{
    bool bIsSafe = true;
    for(int i = 0; i < positions.size(); ++i) 
    {
        Point point = positions[i];
        if(point.x != position.x || point.y != position.y) 
        {
            if(position.y == point.y) 
            {
                bIsSafe = false;
            }
            if(abs(position.y - point.y) == abs(position.x - point.x)) 
            {
                bIsSafe = false;
            }
        }
    }

    return bIsSafe;
}

bool placeQueen(int i) 
{
    bool bIsGoodPos = false;
    for(int j = 1; j <= GRID_SIZE && bIsGoodPos == false; j++) 
    {
        Point p(i, j);
        positions.push_back(p);
        if(verifyPos(p) && (i == GRID_SIZE || placeQueen(i + 1))) 
        {
            bIsGoodPos = true;
        }
        else 
        {
            positions.pop_back();
        }
    }
    return bIsGoodPos;
}


int main(void) 
{
    int i = 1;
    placeQueen(i);
    for(int i = 0; i < positions.size(); ++i) 
    {
        Point p = positions[i];
        cout << "(" << p.x << "; " << p.y << ")" << endl;
    }

    return 0;
}

回答by 3dmaze

It seems that for code that requires not too much memory access and intensive computing the difference between Java an C++ is low. But in the opposite situation the difference looks amazing :

对于不需要太多内存访问和密集计算的代码,Java 和 C++ 之间的差异似乎很小。但在相反的情况下,差异看起来很惊人:

test.java

测试.java

import java.lang.String;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

public class test{
    private static Random gna=new Random();

    public static double new_value(double value){
        if (value<0.5) value=0;
        return value*value;
    }

    public static void main(String[] args) {
        long start_time = System.currentTimeMillis();   
        List<Double> ze_list=new ArrayList();
        for (int i=0;i<1e8;i++){
            double temp=new_value(gna.nextDouble());
            ze_list.add(temp);
        }
        long end_time = System.currentTimeMillis();
        System.out.println("Time (s) :"+ ((end_time-start_time)/1000));
        Scanner input = new Scanner(System.in);
        String inputval = input.next();
    }
}

and compare it to test.cpp:

并将其与test.cpp进行比较:

#include <iostream>
#include <vector>
#include <ctime>
#include <random>
using namespace std;

static default_random_engine dre1(time(0));
static uniform_real_distribution <double> urd1(0, 1);

static double new_value(double value){
    if (value<0.5) value=0;
    return value*value;
}

int main(void){
        time_t tbegin,tend;
        double texec=0;
        tbegin=time(NULL);
        vector<double> ze_list;
        for (int i=0;i<1e8;i++){
            double temp=new_value(urd1(dre1));
            ze_list.push_back(temp);
        }
        tend=time(NULL);
        texec=difftime(tend,tbegin);
        cout << "\nTime (s) " << texec << " s\n";
        int val=0;
        cin >> val;
    return 0;
}

I just tested it on my Mac :

我刚刚在我的 Mac 上测试了它:

  • the Java version took 90s and required 3.77 Go
  • the C++ programm took 2s and required only 770 Mo
  • Java 版本花了 90 年代,需要 3.77 Go
  • C++ 程序耗时 2 秒,只需要 770 个月

Maybe there is a possibility to increase Java performances but I cannot see how.

也许有可能提高 Java 性能,但我不知道如何。