Performance-Problem: Java vs C++
Habe ich immer gehört, dass C++ war viel effizienter als Java ist (und das ist der Grund, warum die meisten Spiele sind in C++ entwickelt).
Schrieb ich einen kleinen Algorithmus zur Lösung des "Acht Königinnen-Rätsel" in Java und C++, mit der exakt gleichen Algorithmus, und begann dann, Sie zu erhöhen, die Anzahl oder Quadrate.
Bei erreichen checkboards von 20*20 oder sogar 22*22, es wird angezeigt, Java ist viel effektiver (3 Sekunden vs 66 Sekunden für C++).
Ich habe keine Ahnung, warum, aber ich bin mir ziemlich Anfang mit C++, so dass es möglich ist, dass ich einige riesige performance-Fehler, so will ich gerne akzeptieren, alle Informationen, die mir helfen würden zu verstehen, was geschieht.
Unten ist der code, den ich verwenden in 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;
}
}
Und unten ist der code, der in 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;
}
- Hast du das kompilieren von C++-Code mit Optimierung aktiviert? Für gcc und clang hinzufügen
-O3
auf der Kommandozeile. - verwenden Sie einen Vektor und nicht einer Liste...das Durchlaufen einer Liste in jeder Sprache ist schrecklich.
- Erstens, nutzen
std::vector<Point>
stattstd::list<Point>
. Versuchen Sie dann, die übergabe per Referenz statt als Wert. Zum Beispielbool verifierNonPrise(const Point& emplacement)
. Als Nächstes erstellen Sie nicht benannt Provisorien, sondern tunpositions.emplace_back(i, j);
. Es ist wahrscheinlich, es gibt viele andere Dinge, die Sie verbessern können. - "Ich habe immer gehört, dass C++ war viel effizienter als Java"-weil es allgemein ist.
- Es ist überhaupt nicht ungewöhnlich für Java zu schlagen C++. Ein JITC-optimierte Java-Programm kann mehr dicht optimiert, als möglich unter Verwendung leicht Verfügbarer C++ - compiler/linker. ZB, ein JITC kann einfach inline-Operationen auf einen Punkt, während C++ können in der Regel nur tun, wenn die Funktionen deklariert sind, inlineable.
- Als die Sprache näher an Maschinensprache (die tiefer liegenden Ebene eine Sprache ist), Sie haben mehr Knöpfe zur Steuerung Zeug und dies können Sie entweder machen oder brechen Sie Ihre code-je nachdem, wie Sie verwenden Sie diese regler. Wenn Sie nach oben schauen alle den Vergleich von Fällen, hier findest du viele Beispiele, wie schnelle C++ - code einen code, der ursprünglich langsam sehr schnell. Die meisten der Zeit, die Sie nicht tun können, die in höheren Sprachen. Dies bedeutet nicht, dass alle C++ - codes gehen, um schneller als JAVA, PYTHON ... es bedeutet nur, Sie machen den code schneller.
- Nur ein kleiner Punkt, der wahrscheinlich nicht auf die Leistung sehr viel. Wenn alle Ihre point-Klasse hat halt
x
undy
, und es gibt keine Invarianten aufrecht zu erhalten, könnte man genauso gut entfernen Sie die member-Funktionen und die Daten der Mitglieder der öffentlichkeit. - Beachten Sie, dass die Deklaration der Funktionen inlinable hat wirklich keine bearance, ob Sie inline. In diesem Beispiel
Point
's Methoden sind implizit inline. Aber Sie sind auch nicht notwendig. Die Daten sollten öffentlich sein. - In Java jede (nicht-native) Funktion inlined, wenn der JITC entscheidet, es lohnt sich. In C++, wenn eine Funktion in einer anderen compilation unit, es kann nur eingebettet, wenn der linker ist sehr, sehr smart, oder wenn der compiler effektiv kompiliert alles.
- Und eine Folge ist, dass in der JITC-optimierte Java getter-und setter-Funktionen sind "frei" -- null-Kosten vs Zugriff auf die Variablen direkt.
- Diesen Reglern werden in der JVM für Java, nicht für den compiler. Die Hotspot-Optionen kann einen sehr großen Unterschied.
- Sicher, aber OP ' s code, alles inline. Der performance-hit ist wahrscheinlich die Verwendung von
std::list
. Für die Getter würden diese optimiert werden, auch wenn inlined, aber mit Ihnen könnte resultieren in zusätzlichen Kopien der Daten der Mitglieder aus, weil Sie semantisch Werte zurückgeben. Jedenfalls ist es schwer zu sehen, wie Java konnte-ausführen von C++ in solchen einfachen numerischen problem, wenn richtig codiert, die in beiden Sprachen. Ich würde nicht erwarten, dass C++ zu Massiv aus-ausführen Java entweder. - Ich habe nicht bedeuten, andere Sprachen haben nicht diese Kontrollen, ich meinte, wie Sie näher an der Maschine Sprache, die Sie haben, mehr von diesen kontrolliert. Aber Sie haben absolut Recht.
- Und solche smart-linkers vorhanden. Jeder gute compiler wird heute Optionen für inter-Modul-Optimierung. Die großen Unterschiede kommen von anderen Dingen: für einige Arten von Anwendungen, wie zum Beispiel die garbage collection wird ein großer Sieg, für die anderen mit zuteilen, alles dynamisch wird Sie töten. (Ich würde erwarten, dass seine zu den letzteren; er hat keine dynamische Zuordnungen, was so überhaupt, außerhalb seiner Liste. Aber die Tatsache, dass jeder push_back und pop_back zuordnen muss/frei ist, und das fehlen von Lokalität sind Mörder.)
- Wenn richtig codiert und kompiliert mit Optimierung. Mit Java, brauchen Sie sich keine sorgen über die optimziation; JIT entscheidet, Wann und wo. Mit C++, müssen Sie dem compiler zu optimieren. (Und während ich würde nicht erwarten, dass ein massiver Unterschied, die Tatsache, dass er sich dynamisch zuweisen und jeden
Point
in Java könnte einen signifikanten Unterschied machen. Ich weiß nicht, ob die neuesten JIT-würde in der Lage sein, die Beseitigung, die.) - Plus die JIT-tatsächlich zu laufen. Und der garbage collector auch. BTW, ich vergaß, dass die benutzerdefinierten Typen zugeordnet werden musste dynamisch in java. Ich dachte, der array-basierte Probleme. Ich würde auch erwarten, dass diese einen Effekt haben.
- Läuft der JIT kann ein Problem sein, besonders für ein kleines Programm wie seine. (Versuchen Sie, seinem Beispiel zu eine Millionen mal, und Sie können Sie ignorieren, die JIT.)
- Und je nach code, der garbage collector kann schneller sein als die manuelle Zuordnung und die erforderlichen befreit. In seinem code, ist es fast sicher, dass die Gesamtkosten einer Zuweisung in Java billiger sein wird, als in C++, da er nie verwendet, genügend Speicherplatz für das auslösen der Sammler. Und selbst wenn Sie sich wiederholen, eine million mal, dies wäre wahr, weil Sie im optimalen Fall für die GC. Aber selbst der Schnellste Zuteilung ist langsamer als keine dynamische Allokation.
- Wenn ich sehe, wie
push_back
ich erschaudern. Es gibt so viele Dinge, die jedes Programm langsam, andere als die Wahl der Sprache. Einige Menschen, die "grün um die Kiemen" zu denken, dass die Optimierung ist alles über compiler-Optimierung, wenn in der Tat, das sollte die Letzte Sache, die Sie betrachten. - Etwas zu merken, ist, dass Ihre Wahl von einem compiler hat einen realen Einfluss auf die Leistung. In einigen benchmarks, C-code, kompiliert mit gcc nicht laufen alle schneller als Java kompiliert mit einem guten compiler. Finden Sie diese stefankrause.net/wp/?p=6 und das stefankrause.net/wp/?p=6 für mehr info
- C++ - code verwenden können, eine benutzerdefinierte Zuweisung (die aggregierten Zuweisungen und tun, nur ein einzelnes, frei später.) Das ist sogar noch schneller. Oder lassen Sie das frei heraus ein Vertrauen auf OS cleanup verlassen.
- Vielleicht. Das ist mehr oder weniger wie die garbage collection funktioniert. Als einfach verlassen, das frei heraus; das ist genau das, was passiert, wenn Sie nicht genug Speicher, um garbage collection auszulösen (mit dem zusätzlichen plus, dass die Zuteilung algorithmen rechnen, die garbage collection sind schneller in der Verteilung). Natürlich in C++, können Sie verwenden einen garbage collector auch für die Fälle, in denen es die bessere Lösung ist.
- Eigentlich, mit diesem Teil habe ich gemeint: Verwenden Sie eine Zuweisung explizit nicht unterstützt Freigabe an alle: Schneller und effizienter als die normale manuelle Freigabe sowie alle Müll-Sammler, selbst wenn es nie löst. (Das ist eine Optimierung für eine wirklich kleine Nische mit anständigen Dividenden...)
- Ich sage Ihnen etwas - wenn Sie nicht planen, machen advenced Methoden (zum Beispiel in der künstlichen Intelligenz), der sollte ultra "optimiert", und jede Millisekunde wichtig ist... oder erweiterte Berechnungen in Grafik-oder ... etc.. Es ist nicht nötig, sich zu kümmern "C++ schneller als Java" - ja ist es, aber heute haben wir mächtig genug computer, um Sie nicht kümmern über eine solche Leistung in jedem normalen programm (natürlich sage ich nicht, dass über tradicional Optimalisierung wie makind nicht benötigt-loops 😛 ).. Java ist mächtig, denn Sie können die Verwendung von java fast überall mit hudge Bibliotheken unterstützen 😉
- Alle allocators, die ich gesehen habe, die keine Unterstützung für die Freigabe auf alle arbeiten sehr viel, wie die allocators ein kopieren garbage collector; die Zuteilung der Zeit ist sehr, sehr schnell. Wo die garbage collection Kosten mehr in solchen Fällen ist, wenn es ausgelöst wird, und wenn Sie reservieren, wenig genug, so dass Sie nicht brauchen, um freigeben, dann die garbage collection sollte nicht immer auslösen, und Sie enden mit der Ausführung im wesentlichen den gleichen code.
- Es hängt davon ab. Java ist sehr schlecht für numerische Anwendungen, wo Sie eine Menge von sehr kleinen Arten mit Wert-Semantik. Der JIT-nicht immer finden alle die Fälle, wo Sie konnten", so dass Sie am Ende mit zusätzlichen Zuweisungen, etc. die Kosten signifikante Echtzeit. Natürlich, der wahre Grund für Java nie benutzt wird, in solchen Fällen ist, dass die Sprache nicht ausdrucksstark genug, um lesbaren code schreiben für Sie. Am Ende, Java ist nicht für große scale-Programmierung, und es ist sehr schwierig zu schreiben, lesbar, zuverlässig-code in Java.
- Aber der GC muss Kenntnis von der Art und Größe des jede Zuordnung. Die C++ - Lösung braucht es nicht, überhaupt, so die Verringerung der Zeit, die für die Zuteilung und die Größe der Zuweisungen.
- sicherlich tut es wissen müssen, oder zumindest die Größe, als wenn Sie verstreut Blöcke von freigegebenen Speicher unter Speicher zugewiesen ist, an einem gewissen Punkt (wenn kein zusammenhängender block groß genug für seine nächste Zuteilung) hat es zu unterbrechen (wie ein gc, obwohl aus einem anderen Grund) und kompakte Speicher?
- dies zeigt, man braucht eine Lizenz zur Verwendung von C++ (wie Sie eine Lizenz für eine Pistole)
- Sry, aber du bist fehlt den Punkt: Wenn es keine Freigabe, es gibt keine Fragmentierung, keine Notwendigkeit für die Verfolgung von Arten, Größen und dergleichen.
- Es gibt keine Programmier-Lizenz noch. Wie auch immer, wer wäre kompetent, Willens und vertrauenswürdig zu bewerten die Kompetenz von PHP, Java, Perl, C#, C++, [insert Programmiersprache] Programmierer?
- was ich meine ist, dass, um frei, dass der Speicher irgendwann (es sei denn, Sie verwenden ein Betriebssystem, das nicht verwalten, Speicher) würde ich mir vorstellen, so etwas ist automatisch mit der Aufzeichnung der Größe der Zuweisung, und wie es sich durchsetzt unter Zuordnungen für andere Anwendungen (von denen jeder machen kann, - Freigabe und Fragmentierung etc.).
- Aber wenn Sie nicht wnat, um den Speicher frei bisher, so dass es zu dem OS zu bereinigen, die auf Prozess beenden (was es ohnehin tun), es gibt keine Notwendigkeit zu halten Spur von jeder der Informationen, die notwendig ist, um freie zugewiesenen Blöcke, damit Sie nur nicht.
- ja, macht Sinn. Ich dachte, ich würde es nicht, wenn Sie befreit es, aber wenn es tut, so oder so, warum dann nicht.
- Ich würde wirklich empfehlen Sie nicht die Verwendung andere Sprache als Englisch für Variablen und Funktion von Namen. Manchmal ist Ihr code wird gelesen von Menschen, die nicht Französisch verstehen (wie, glaube ich, hier bei stack-overflow), das macht es schwerer für Sie, Lesen Sie Ihren code.
Du musst angemeldet sein, um einen Kommentar abzugeben.
std::list
in C++ ist eine verknüpfte Liste, in der Erwägung, dassjava.util.ArrayList
ist ein array. Versuchen Sie ersetzenstd::list
durchstd::vector
. Auch, sicher sein, zu kompilieren mit Optimierung auf.Point
Objekt ist nicht groß). Auch, welche compiler verwenden Sie? Für mich Ihre ursprünglichen C++ - code ist bereits schneller als der original-Java-code bei der Kompilierung mit Optimierung (g++-4.9 -O2
).int
vs. C++ - code mitdouble
ist kein fairer Vergleich.verifierNonPrise
mitstd::find_if
std::list
Struktur ist weniger effizient, für dieses Programm alsstd::vector
. Ist es nur eine Frage, dass die grundlegenden Operationen (z.B. Zunahme von ein iterator) auf eine (doppelt verkettete) Liste benötigen mehr Zyklen als für einen Vektor, oder gibt es Sachen, die sind grundsätzlich langsamer für Listen (wie das element access by index)? In anderen Worten, führen Sie die beiden Implementierungen die gleiche asymptotische Komplexität nur mit einem Konstanten Faktor zwischen Ihnen, oder nicht?vector
auswirken können (mehr cache-freundlich).Updates:
Änderungen an C++
Zusammenstellung Scheitern
27610 Millisekunden
4416 Millisekunden
2294 Millisekunden
2384 Millisekunden
2351 Millisekunden
std::find_if
929 Millisekunden
549 Millisekunden
Änderungen an Java -
3459 Millisekunden
verifierNonPrise
frühe Rückkehr368 Millisekunden
Java Vs C++
Der Endgültige Code:
#include <algorithm>
und#include <chrono>
fehlen (nicht kompilieren auf meinem compiler auch ohne Sie). Auch, -O3 und -Ofast nichts ändern für die timings. Irgendwelche Gedanken, warum?Replace std::list with std::vector
,Replace Point with std::pair
undMade verifierNonPrise const correct
wirklich anders-oder sind die Unterschiede nur mess-imprecisions?verifierNonPrise
.std::list
mitstd::vector
. ErsetztPoint
mitstd::pair<double, double>
dann ersetzt alledouble
mitint
.verifierNonPrise()
zurück so bald wie möglich. Nun die Zeiten sind vergleichbar.<iostream>
und verwendenprintf
statt? Das sollte deutlich beschleunigt werden.push_back
wenn keine überlappung gefunden für das neue, durch die Vereinfachung der Logik zu entfernen (unnötig benannte Variablen, entfernen von bedingten mit der Feststellung, dass die Zeilen ausgewertet werden (in aufsteigender Reihenfolge) und entfernen derabs
, und dadurch diestd::find_if
über eine weniger element: coliru.stacked-crooked.com/a/2915144fc0c2a75e Auf Coliru, reduziert sich die Laufzeit von 1511ms zu 1130ms (-25%). Natürlich, YMMV, und Java könnte auch von diesen Veränderungen profitieren.cout << "(" << it->first << "; " << it->second << ")" << endl;
- sollte nicht sein, das Spülen der stream nach jeder line -endl
sollte ersetzt werden, mit'\n'
. Beachten Sie, dass der Java-code istSystem.out.println("(" + point.x + "; " + point.y + ")");
ist nicht bündig, denn es gibt keinen Zeilenumbruch.inline
vorangestelltverifierNonPrise
auch, obwohl es war hoffentlich sein inlined sowieso, und ein cleanup auf den lambda return "X & Y" anstelle desif (X) if (Y) return true; return false;
Tanz... wohl auch irrelevant.Test dieser version, aktualisiert mit C++11-features. Getestet in GCC 4.9.0 mit
-std=c++11
. Getestet auf Celeron 1.6 GHz, 512 MB RAM.Zeiten in meinem PC:
Original: Dauer (Millisekunden): 12658
Erste Version: Dauer (Millisekunden): 3616
Optimierte Version: Dauer (Millisekunden): 1745
Änderungen sind:
vector
stattlist
Benchmark, und Worte von Stroustrup.Quelle:
Etwas mehr Tiefe verpasst.
Änderungen:
Quelle (einige Empfehlung aktualisiert):
std::pair
? Aus einer Sicht des design, es ist definitiv etwas, was Sie vermeiden wollen. Ich zweifle auch daran, dass mitemplace_back
macht einen erheblichen Unterschied; es ist mehr fein-tuning. (Mitstd::vector
- und referenzübergabe sind zweifellos die großen Gewinne.)emplace_back
nicht gewinnen, nichts habe ich geändert, weil denke, dassemplacement
variable in der MethodeplacerDame
war nur für das einfügen in dievector
rückgängig zu machen und wenn Sie sehen, der Aufruf zuverifierNonPrise
, aber vergessenemplace_back
. Der Grund fürstd::pair
war, dass es keinen Grund gibt, eine Klasse zu erstellen für etwas, STD cover, ist nur mehr code pflegen, mehr code zu testen, auch wenn ist so trivial, undstd::make_pair
(in einigen Compilern nur eine Zuteilung für die 2 Arten), in diesem Fall ist nicht viel, aber die Schaffung von 1 Million Paare, das wäre ein Unterschied.std::vector
hier. Es wäre viel sauberer, und nicht langsamer, Sie zu einer Klasse. Oder, da du dich mit C++11, eine Struktur mit Liste der Initialisierung. Und natürlichstd::pair
ist Verschleierung, denn die Mitglieder sind der nicht ersten und zweiten, aberx
undy
(das hat eine klare semantische Bedeutung);std::pair
ist praktisch für schnelle Experimente, aber Ihre Verwendung ist ein anti-pattern in der ernst-code.const
helfen nicht dem compiler zu optimieren, da der compiler kann nicht davon ausgehen, dass das Objekt geändert wird nicht durch einen anderen Pfad. (Auf der anderen Seite, Sie helfen die Lesbarkeit zu verbessern.)std::list -> std::vector
undPoint -> std::pair
die beste Verbesserung, die ich bekam, war der Einsatz vonstd::find_if
statt eines expliziten Schleife.positions[i].x == i
. Dies bedeutet, dass die Speicherung der x-Koordinate ist überflüssig. Sie können lassen Sie nur die y (und verwendenstd::vector<int>
).Vergleich verwaltet, dynamisch kompilierten Sprache wie Java eine statisch kompilierte Sprache wie C++, ist sehr schwierig.
Werden Sie immer äpfel mit Birnen vergleichen in einem gewissen Sinne, denn Sie sind konzeptionell sehr unterschiedlich. Es beginnt mit der Nutzung von standard-Bibliotheken (ArrayList vs std::list/vector), die möglicherweise völlig unterschiedliche Leistungsmerkmale, auch dein code sieht ähnlich aus in beiden Sprachen.
Dann ist es die inhärente problem mit microbenchmarks in Java (kurzer test in Java immer langsamer, weil die JIT beobachten den Programmablauf, bevor er entscheidet, was und wie es zusammengestellt werden). Gleiches gilt für die compiler-Optionen für C++, auch die Struktur der source-code (unabhängig kompiliert und verlinkt Klassen im Vergleich zu single-Datei, Quelle) einen großen Unterschied machen kann (weil es ändert sich die Höhe des "Einblick" der C++ - compiler in den anderen Klassen).
Nächstes wird der Allgemeine Unterschied in der memory management, garbage collection-vs-Handbuch memory management (smart pointers etc. sind immer noch als die manuelle Speicherverwaltung).
Nicht zu erwähnen, die Allgemeine Sprache Unterschiede wie müssen Sie explizit deklarieren eine Methode virtual in C++ und in Java jeder member-Methode ist standardmäßig virtuell (arbeiten Sie heraus, ob es wirklich virtuell zur Laufzeit ist in der VM).
... Mit alle diese Unterschiede wird es immer Fälle geben, in denen eine Sprache haben einen massiven Vorteil gegenüber den anderen. Ein einfacher test mit sehr begrenzten Rahmen (wie dein test hier) sagt sehr wenig über jede Sprache als ganzes.
Ein weiterer Punkt, den Menschen neigen oft dazu, zu ignorieren, ist: Wie produktiv kann man mit einer Sprache, Geschwindigkeit ist nicht alles (Aussehen, wie erfolgreiche Skript langages sind in einigen Bereichen, trotz kaum konkurrenzfähiger, wenn man nur bei der Ausführung Geschwindigkeit). Mangelnde Leistung kann lähmend sein, aber so kann die geringe Produktivität.
Ich kann schlagen ein Totes Pferd hier, aber Sie einfach tun, eine Zeile für Zeile übersetzung von Java zu C++, auch nicht mit const Referenz-Parameter oder eine solche Sache, die Sie sehen können, C++ ist fast doppelt so schnell wie Java.
Alle die "syntaktische-Optimierung" emplacing etc. hat wenig Wirkung, wenn jede...
Queen.java (ins englische übersetzt)
Queen.cpp
C++ machen kann in 21 ms (auf einem alten core i7-860), wenn Sie bit-Karten. Für die timing-run, den ich auskommentiert, die showSoln () - Aufruf, da der eine grafische Darstellung der Schachbrett dauert doppelt so lange, als das finden der Lösung.
Auch, es gibt keinen Grund für die Verwendung von float/doouble-Typen, die für die Koordinaten.
Sollten Sie die Leistung erhalten, wenn Sie nicht mit Gewalt aufrufenden floating-point-abs-library-Aufruf in der C++ -
Java speichert die Koordinaten als integer. Die get-Funktionen geben Doppel, doch dies ist wohl leichter zu optimieren, der Weg in Java, dann in c++.
Es scheint, dass der code, der benötigt nicht zu viel Speicher zugreifen und intensive computing der Unterschied zwischen Java eine C++ ist gering. Aber in der umgekehrten situation den Unterschied sieht toll aus :
test.java
und vergleichen Sie es test.cpp:
Habe es gerade getestet auf meinem Mac :
Gibt es vielleicht eine Möglichkeit, die Java-Leistungen, aber ich sehe nicht, wie.
Java übergibt Objekte um Methoden-Referenzen und die Referenzen als Wert übergeben werden, aber C++ geht Gegenstände von Wert.
Sollten Sie C++ - code machen es gleich wie Java (Übergeben von Zeigern in C++ intstead der übergabe von Objekten):