C++ Performance von C++ - aktueller Stand?

convexus schrieb:
- Der Java Compiler ist in C++ programmiert, warum wohl?
- Der C# Compiler ist in C++ programmiert.
Stimmt, das liegt aber hauptsächlich daran, dass C++ schon da war als die Java und C# "erfunden" wurden. Ein klassisches Henne-Ei-Problem. Der erste C Compiler wurde auch nicht in C geschrieben.
convexus schrieb:
Die Vorteile von C++ liegen imo in den Möglichkeiten die die Sprache bietet. Sie unterstützt ziemlich alle Programmierparadigma inklusive Generische Programmierung bei den der Template-Mechanismus als funktionale Programmiersprache funktiert, welche der C++ Compiler zur Compile-Zeit ausführt.
Sowohl C# als auch Java (Java allerdings nur zur Compilezeit, C# auch zur Laufzeit) können Generics. C/C++ kann halt Pointer (C# theoretisch auch, aber nur wenn man mit "unsafe" kompiliert), ob das jetzt so gut ist muss jeder selbst beurteilen. Die meisten "neueren" Sprachen und die meisten Programmierer kommen auch ohne aus.

Wie gesagt: Alle Sprachen haben ihre Vor- und Nachteile und damit ihre Anwendungsbereiche. Welche die richtige ist sollte man im Einzelfall entscheiden.
 
antred schrieb:
dynamic_cast und RTTI, da stimme ich dir zu (wobei man die bei anständigem Design eigentlich so wie so nicht brauchen sollte). Aber deine ablehnende Haltung gegenüber den Standardcontainern kann ich so ganz und gar nicht teilen. Ich würde mal sagen, daß die Standardcontainer in 90% der Fälle weitaus performanter sind, als alle vergleichbaren selbstgebastelten Container, und in den 10% wo das nicht stimmt, macht die Differenz wahrscheinlich nur in einem Zehntel der Fälle einen signifikanten Unterschied für die Anwendung.
Da hab ich mich nicht richtig ausgedrückt, die Standardcontainer sind alle recht gut und auch schnell (verwende sie oft genug selbst :D), aber wenn man mit den Kanonen auf Spatzen schießt, dann wirds langsam. (Bspw. ein vector bei maximal 10 Elemente a 16 Byte -> besser statisches Array mit Zählvariable, Speed: 1:~10)

Die Kompatibilität ist auch eine wichtige Sache, ich freu mich jedes Mal, wenn ich ein Programm so schreiben kann, dass es wirklich nur eine Datei ist, und diese dann nur Abhängigkeiten von kernel32 und co hat.

In Java: Für Hello World erstmal 10 MB runterladen...
In C#: erstmal .Net FW ziehen...
 
TheCadillacMan schrieb:
Stimmt, das liegt aber hauptsächlich daran, dass C++ schon da war als die Java und C# "erfunden" wurden. Ein klassisches Henne-Ei-Problem. Der erste C Compiler wurde auch nicht in C geschrieben.

Das Henne-Ei Problem stellt sich bei Compiler-Sprachen häufig nicht; man programmiert einen Interpreter für die Zielsprache (Minimalistisch) und den Compiler in der Zielsprache selbst. Dann kann man sich bildlich gesprochen an den eigenen Haaren aus dem Sumpf ziehen. (siehe auch http://de.wikipedia.org/wiki/Bootstrapping_(Programmierung)

TheCadillacMan schrieb:
Sowohl C# als auch Java (Java allerdings nur zur Compilezeit, C# auch zur Laufzeit) können Generics. C/C++ kann halt Pointer (C# theoretisch auch, aber nur wenn man mit "unsafe" kompiliert), ob das jetzt so gut ist muss jeder selbst beurteilen. Die meisten "neueren" Sprachen und die meisten Programmierer kommen auch ohne aus.

Ich weiss zwar, das C# und Java bzgl. generische Programmierung zugelegt haben, glaube aber nicht das sie diesbezüglich mit C++ 'vergleichbar' sind. In C++ lassen sich Programme für den Compiler schreiben zB. die Berechnung eines Folgeglieds der Fibonnacci-Folge. Die Berechnung erfolgt dann während der Kompilierung durch den Compiler. Es ist sogar so, dass C++ Template-Mechanismus alle berechenbaren Funktionen abbilden kann. Von dieser Möglichkeit wird bei C++ Bibliotheken reger Gebrauch gemacht (Boost, Blitz++..) Eine wirkliche sinnvolle Anwendung hierfür sind die DSEL (domain spezific embedded language), welche C++ einen vollkommen neuen Rahmen geben können. Ein Beispiel aus der Blitz++ Bibliothek:

Code:
#include <blitz/array.h>

using namespace blitz;

int main()
{
    Array<float,2> A(3,3), B(3,3), C(3,3);

    A = 1, 0, 0,
        2, 2, 2,
        1, 0, 0;

    B = 0, 0, 7,
        0, 8, 0,
        9, 9, 9;

    C = A + B;

    cout << "A = " << A << endl
         << "B = " << B << endl
         << "C = " << C << endl;

    return 0;
}

Im Beispiel kommt auch Operator-Overloading zur Anwendung. Die Matrix-Addition wird mittels sogenannte Expression-Templates ausgewertet. Wichtig ist zu einem, dass man für die Anwendung die Template-Programmierung nicht beherrschen muss und das der erzeugte Code geschwindigkeitstechnisch fast mit Fortran gleichzieht. (siehe http://www.oonumerics.org/blitz/)
 
Zuletzt bearbeitet: (Ausdruck)
Blitzmerker schrieb:
(Bspw. ein vector bei maximal 10 Elemente a 16 Byte -> besser statisches Array mit Zählvariable, Speed: 1:~10)

Also 'tschuldigung falls ich ein bißchen feindseelig wirke, aber ... glaub'sch ned. ;)

Wenn du überhaupt irgendeinen signifikanten Geschwindigkeitsunterschied zwischen einem Array und einem vector festgestellt hast, dann hast du meiner Meinung nach entweder eine zweitklasse STL-Implementierung verwendet, oder da waren irgendwelche Debug-features noch aktiv.

Oder wie bist du auf den Faktor 10 gekommen?

Und falls du für so simple Sachen absolute keinen vector verwenden möchtest: http://www.boost.org/doc/libs/1_45_0/doc/html/array.html
 
Zuletzt bearbeitet:
Ich habe übrigens noch nie gelesen oder festgestellt dass Vektoren in C++ langsam sein sollen. Du brauchst ja oft genug auch Vektoren bei kleinen Indizes, da bei Arrays ja in C++ zur Compilezeit die Größe bekannt sein muss und eine dynamische Speicherallokierung nicht erlaubt ist (im Gegensatz zu C)
 
Blitzmerker schrieb:
.....
In Java: Für Hello World erstmal 10 MB runterladen...
In C#: erstmal .Net FW ziehen...

wo hast du denn diese zahlen her ? xD

Code:
class HelloWorld{
   public static void main(String args[]) {
       System.out.println("Hello World");
   }
}

die compelierte datei ist nur ein paar kb groß, da alles andere schon in der vm ist. Und die zu installieren ist eine einmalige sache, bei vielen PC's heute sowieso schon dabei unbd wenn nich is das netz i.d.r. schnell genug das es nur ein paar minuten in anspruch nimmt.

Von der größe des Quellcodes ist der Unterschied nicht wirklich so groß das er ins gewicht fällt, höchstens besteht die möglichkeit das ein c++ code wesentlich kompakter geschrieben werden kann.

Aber ich schleiße mich den früher genannten meinungen auch an, es ist wohl ehr anwendungsabhänig welche Sprache man benutzt. Und die Java VM's werden auch immer schneller, von den CPU's und den libs ganz zu schweigen. Aber da bin ich auch ein wenig voreingenommen da ich mich mit Java einfach "am wohlsten" fühle.
Muss gerade gezwungener maßen eine menge php und JS coden, das geht mir ziemlich gegen den Strich. Da kommt man sich vor als ob man von einem Ferrari auf nen Trabbi umsteigt ^^
 
Nun ja, obs wirklich 1:10 ist weiß ich nicht, aber es war gut und deutlich spürbar.
Das Problem war in diesem Fall, dass dieses Feld/dieser Wert sehr oft angelegt und gleich wieder freigegeben wurde, d. h. der Konstruktor und der Destruktor haben sich massiv ausgewirkt, und die lassen sich nicht einfach wegoptimieren.

Was noch an Debug Zeug aktiv war, war mir dann egal, da das Umschreiben nicht lange gedauert hat.

Aber um die C++-interne Geschwindigkeitsdifferenzen gehts ja hier net, es war nur als Beispiel gedacht.

BTW: Was richtig langsam ist ist der Regex-Teil von VS2008 unter std::tr1, da ist man fast von Hand schneller^^.

@pizza4ever:
Dafür gibts new (und wo darf man in C dynamisch Speicher aufm Stack anfordern? oder meinst du malloc?)

@Mercsen:
Die VM ist nicht gerade klein und bei eingeschränkten Rechten auch nicht so einfach und ich kenn mehrere Programme, die komplett JRE mitbringen.

Und vergleich nicht Java mit JS und PHP, Java wird kompiliert (nach Bytecode) PHP und JS wird immer interpretiert (oder JIT kompiliert).
 
Zuletzt bearbeitet:
Naja das einjge programme die komplette JRE mitbringen kann man ja nun schlecht Java zu lasten legen.....
Das man PHP nich mit Java vergleichen kann ist mir ebenso klar, wie das PHP interpretiert und java zuerst in eine für die VM verständliche form kompiliert wird.....
ich wollte damit nur meiner aussage ausdruck verleihen das ich mich für die Sprache entschieden habe bei der ich mich am besten aufgehoben fühle. Bei PHP fühle ich das einfach nicht denn es ist auch etwas anderes (nämlich eine script sprache).
Nur leider war es vom Kunden gewünscht :(
 
int array_breite = Bild1.width - Bild2.width;
int array_hoehe = Bild1.height - Bild2.height;
int testarray[array_breite][array_hoehe]

sowas schluckt ein c++ compiler (beim MS compiler: C2133) nicht. ein c compiler müssts eigentlich schlucken da dort VLAs möglich sind. New wäre uU auch noch ne Möglichkeit, aber ich nehm immer std::vector
 
um das ganze mal noch weiter aufzupeppen:
was halten die oldschool-gccler von llvm/clang.

ist ja schon eine heiße sache, dass da in bruchteilen der zeit teils schnellerer code als bei gcc rauskommt.
 
convexus schrieb:
Das Henne-Ei Problem stellt sich bei Compiler-Sprachen häufig nicht; man programmiert einen Interpreter für die Zielsprache (Minimalistisch) und den Compiler in der Zielsprache selbst. Dann kann man sich bildlich gesprochen an den eigenen Haaren aus dem Sumpf ziehen. (siehe auch http://de.wikipedia.org/wiki/Bootstrapping_(Programmierung)
Dass es technisch möglich ist ist mir schon klar. Ich will mehr darauf hinaus, dass es bedeutend einfacher ist einen Compiler in einer schon vorhandenen Sprache mit schon vorhandenen Werkzeugen und Programmierern zu schreiben. Außerdem muss man bedenken, dass Java und C# in der ersten Version bei weitem nicht die Möglichkeiten hatten, die sie heute haben.
Der C#-Compiler von Mono wurde übrigens in C# geschrieben. Allerdings erst Jahre nach dem von Microsoft.
 
pizza4ever schrieb:
int array_breite = Bild1.width - Bild2.width;
int array_hoehe = Bild1.height - Bild2.height;
int testarray[array_breite][array_hoehe]

sowas schluckt ein c++ compiler (beim MS compiler: C2133) nicht. ein c compiler müssts eigentlich schlucken da dort VLAs möglich sind. New wäre uU auch noch ne Möglichkeit, aber ich nehm immer std::vector

Man würde den Array dann ja auch so anlegen ;)

Code:
int* testarray = NULL;
int array_breite = Bild1.width - Bild2.width;
int array_hoehe = Bild1.height - Bild2.height;
testarray = new int[array_breite][array_hoehe]
 
Ja ja, in C++ schon. Aber ich glaube, pizza4ever meint, daß es in C (anders als in C++) auch legitim ist, statische Arrays mit nicht konstanten Größenangaben anzulegen.
Keine Ahnung, ob dem wirklich so ist ... ich würde mir lieber die Augen mit einem rostigen Nagel ausstechen als mich mit C herumzuschlagen. ;)
 
Zuletzt bearbeitet:
Ein ganz wichtiger Punkt aus deinem Link: :)

deterministic destruction (allows RAII)

Auf RAII möchte ich um nichts in der Welt verzichten. :) Das ist auch der Grund, weshalb ich an Java ums Verrecken nicht rankomme. Jedes mal, wenn ich dieses häßliche, zum Teil sogar noch mehrfach geschachtelte try-catch-finally Konstrukt sehe, habe ich schwer zu tun, meinen Würgreflex zu unterdrücken.
 
Es ist nicht immer nur der Compiler der die geschwindigkeit vom Programm angibt. Es sind auch die Optimierungen die man selber einprogrammiert und die Laufzeit der algorithmen. Wenn ich meine algorithmen in O(n^2) laufen lasse, da kann mir der compiler auch nicht mehr helfen. Auch mit loop vektorisierung und anderen optimierungen.
 
Ja, das ist sicherlich der größte Faktor, ist aber gerade auch nicht das Thema der Debatte;)
 
völlig korrekt.
hatte mal ein problem wo der speedup nur durch nutzen eines besseren graph-algos etwa 20x war... viel spass mit parallelisierung u.ä. :-P
 
Blitzmerker schrieb:
Nun ja, obs wirklich 1:10 ist weiß ich nicht, aber es war gut und deutlich spürbar.
Also ich bekomme erst bei 100.000 Elementen einen Geschwindigkeitsvorteil des Arrays um 1 ms. :) Bei 1.000.000 sind es immerhin schon 9 ms Vorsprung für das Array, allerdings möchte ich damit nicht arbeiten.
Code:
#define MEM_SIZE 100000

void FillVector( Stopwatch &s, vector<int> &r ) { s.Start(); for( int i = 0; i < MEM_SIZE; i++ ) r.push_back( 0 ); s.Stop(); }
void FillArray( Stopwatch &s, int *r ) { s.Start(); for( int i = 0; i < MEM_SIZE; i++ ) r[i] = 0; s.Stop(); }

int main()
{
  Stopwatch s;

  vector<int> v;
  int *a = new int[MEM_SIZE];

  FillVector( s, v ); cout << "std::vector took " << s.Difference() << " ms" << endl;
  FillArray( s, a );  cout << "array took " << s.Difference() << " ms" << endl;

  system( "pause" );

  return 0;
}
So "langsam" ist ein vector also nicht und die STL gibt es ja nun schon einige Jahre und es wurde bestimmt auch daran optimiert. ;)
 
Zurück
Oben