Performancemythen?
-
Helium schrieb:
DEvent schrieb:
Und meist ist einfacher Code auch schnell.
Das ist ja wohl falsch hoch 10. Dann ist Insert-Sort schneller als Quick-Sort?
Nein, ein Insertsort ist nur nicht so einfach, wie ein Quicksort:
-- quicksort quicksort :: Ord a => [a] -> [a] quicksort [] = [] quicksort (h:t) = quicksort [x | x<-t, x<h] ++ [h] ++ quicksort [x | x<-t, x>=t]
-- insertsort insert :: Ord a => a -> [a] -> [a] insert x [] = [x] insert x (h:t) | x<=h =x:h:t | otherwise = h:insert x t insertsort :: Ord a => [a] -> [a] insertsort [] = [] insertsort (h:t) = insert x (insertsort t)
edit: wieso numeriert er mir den einen Code-Block und den anderen nicht?
Ein Insertsort ist in Sprachen wie C++ einfacher zu schreiben und einfacher zu verstehen wenn man den Code sieht. Und es ist IMHO einfacher zu sehen ob er richtig implementiert ist.
Was nicht heisst dass es weniger Code ist.Anderes Beispiel: Suchen von Strings in langen Texten. Einfach mit binärem Vergleich, also ohne Spielereien wie case-insensitive oder gar ärgeres.
Die einfachste und übersichtlichste Lösung ist hier wohl etwas in der Art:
int find(string text, string find) { int n = text.size() - find.size() + 1; for (int i = 0; i < n; i++) if (text.substr(i, find.size()) == find) return i; return -1; }
Ist aber verglichen mit schlaueren Algorithmen die erstmal diverse Tabellen erstellen (um z.B. zu wissen um wieviel bei einem "mismatch" weitergesprungen werden kann) um einiges langsamer. Je nach Anwendung kann der Unterschied dramatisch sein.
-
ist doch blödsinn. flaschenhälse sind heutzutage doch sogut wie immer netzwerke, datenbanken, festplatten. wer da noch ein i++ durch ein ++i im assembler patcht oder versucht virtuelle methodenaufrufe zu vermeiden hat langeweile aber dicke
-
Ja, nee, is klaaar. Darum gibt es vermutlich auch soviele CPU-Limitierte Games.
-
frenki schrieb:
Ja, nee, is klaaar. Darum gibt es vermutlich auch soviele CPU-Limitierte Games.
CPU-Limitierte Games?
QuickSort ist einfach.
Insert sort ist einfach, weil man nicht ueberlegen muss. Auf QuickSort muss man erstmal kommen.
Aber genau darum ging es mir nicht. Ich sagte nicht: "simpler Code ist schnell", sondern "einfacher Code ist schnell". Wenn der Code klar strukturiert ist, Abläufe klar erkennbar sind und auch schnell zu ersehen ist welcher Teil des Codes was tut, dann ist er meist auch schnell. Oder anders gesagt: ein sauberes Design macht mehr aus als die ganzen low-level hacks.
Leider hat die Strukturiertheit und Ubersichtlichkeit gar nichts mit der Geschwindigkeit des Codes zu tun. Also liegst du schon mal 2 mal falsch.
-
DEvent schrieb:
Aber genau darum ging es mir nicht. Ich sagte nicht: "simpler Code ist schnell", sondern "einfacher Code ist schnell". Wenn der Code klar strukturiert ist, Abläufe klar erkennbar sind und auch schnell zu ersehen ist welcher Teil des Codes was tut, dann ist er meist auch schnell. Oder anders gesagt: ein sauberes Design macht mehr aus als die ganzen low-level hacks.
Leider hat die Strukturiertheit und Ubersichtlichkeit gar nichts mit der Geschwindigkeit des Codes zu tun. Also liegst du schon mal 2 mal falsch.
du hast noch nie an einem mittelgroßen softwareprojekt gearbeitet oder?
-
DEvent schrieb:
Leider hat die Strukturiertheit und Ubersichtlichkeit gar nichts mit der Geschwindigkeit des Codes zu tun. Also liegst du schon mal 2 mal falsch.
Doch, hat es. ...und zwar, wenn Du Dir die Frage stellst, wer den Code geschrieben hat. Dann wirst Du nämlich feststellen, dass Leute mit Erfahrung in der Programmierung, als auch entsprechendem Wissen im jeweiligen Themenbereich, die benötigten Voraussetzungen haben, qualitativ hochwertigen Code zu schreiben. ...und zwar in allen Aspekten. Wer diese Voraussetzungen nicht hat, kann nicht mit einer gleichartigen Systematik an das Projekt herangehen und entsprechend wird da schlechterer Code herauskommen.
-
CStoll schrieb:
@list: Vielleicht sollte doch mal jemand, der den Standard vorliegen hat, die genauen Performance-Anforderungen der list-Methoden nachschlagen (ich habe hier nur Sekundär-Literatur und die liefert widersprüchliche Angaben). Ich kann mir zumindest drei Varianten vorstellen, wie splice() und size() zusammenarbeiten können:
- die libstdc++-Variante: splice() verbiegt nur die Zeiger und size() zählt jedes Mal durch (ergibt O(n) für size()).
- die MSVC-Variante: splice() aktualisiert die Größenangabe (ergibt O(n) für splice().
- lazy evaluation: splice() markiert die Größenwerte als ungültig und size() zählt nach, wenn notwendig (ergibt O(n) im worst case für size() - im Mittel haben beide vermutlich konstante Laufzeit)
Alle drei Varianten sind nach Standard möglich.
-
frenki schrieb:
Ja, nee, is klaaar. Darum gibt es vermutlich auch soviele CPU-Limitierte Games.
nun, die hauptrechenleistung bei spielen geht wohl auf die grafik zurück. die wird zuallererst mal auf der gpu nich auf der cpu berechnet. desweiteren sind grafikberechnungen allesamt nur implementierungen von mathematischen algorithmen. also entweder entwickelt man neue algorithmen oder neue gpus. mit ++i vs i++ kannst du da absolut nichts rausholen.
-
ps: computerspiele sind scheiße
-
dieser thread schrieb:
nun, die hauptrechenleistung bei spielen geht wohl auf die grafik zurück. die wird zuallererst mal auf der gpu nich auf der cpu berechnet. desweiteren sind grafikberechnungen allesamt nur implementierungen von mathematischen algorithmen. also entweder entwickelt man neue algorithmen oder neue gpus. mit ++i vs i++ kannst du da absolut nichts rausholen.
Vielleicht spielt DEvent am Computer eher Schach und eher weniger Killerspiele. ...wer weiß.
-
dieser thread schrieb:
nun, die hauptrechenleistung bei spielen geht wohl auf die grafik zurück.
Eher nicht. Die meiste Rechenleistung wird meistens durch die Logik (KI etc.) verbraten.
-
Gregor schrieb:
Doch, hat es. ...und zwar, wenn Du Dir die Frage stellst, wer den Code geschrieben hat. Dann wirst Du nämlich feststellen, dass Leute mit Erfahrung in der Programmierung, als auch entsprechendem Wissen im jeweiligen Themenbereich, die benötigten Voraussetzungen haben, qualitativ hochwertigen Code zu schreiben. ...und zwar in allen Aspekten. Wer diese Voraussetzungen nicht hat, kann nicht mit einer gleichartigen Systematik an das Projekt herangehen und entsprechend wird da schlechterer Code herauskommen.
Danke, endlich jemand der versteht was ich meine. Wie gesagt: ich will einfachen Code, nicht simplen oder stupiden Code. Man kann auch komplexe Algorithmen klar und einfach implementieren.
-
C ist schneller als C++. Ende.
-
Kenner des Codes schrieb:
C ist schneller als C++. Ende.
Von der Reinen Aussage her ja, genauso wie Assembler schneller als C ist.
Aber in der Praxis gibt es mehr als nur einen reinen Sprachvergleich:
a) Ist der Code noch so gut überschaubar das sich nicht Fehler und Codeduplikate sowie Performancefallen mehren? Zumeist liegt der Vorteil von C++ gegenüber C an der besseren Strukturierung (Wobei vieles an Programmiererfahrung liegt).
b) Der Code mag noch so schnell sein, die Umsetzung muss in der Regel gegen einen Gewissen Zeitdruck erfolgen. Performance ist nicht Alles, sonst würde es keine Sprachen wie Java und C# geben. Man muss immer gewisse Kompromisse eingehen.
cu André
-
asc schrieb:
Kenner des Codes schrieb:
C ist schneller als C++. Ende.
Von der Reinen Aussage her ja, genauso wie Assembler schneller als C ist.
Beides Blödsinn.
-
Cpt. Nukem schrieb:
Man liest ja hier öfters OOP ist langsamer als ohne OOP oder ++iter statt iter++.
Dazu vielleicht mal etwas Klartext:
int & int::operator ++() // ++i { value = value + 1; return this; } int int::operator ++( int ) // i++ { int temp = value; value = value + 1; return temp; }
Du siehst, die Postfix-Variante benötigt ein temporäres Objekt und hat daher mehr Aufwand.
Das Objekt ist in diesem Fall (int) kein erwähnenswertes Problem. Ergo auch kein Problem, da der Compiler das hier ausgleichen kann:int & int::operator ++() // ++i { value = value + 1; returncode = value; } int int::operator ++( int ) // i++ { returncode = value; value = value + 1; }
Hier werden Objekte kopiert, was bei Integers durch die CPU problemlos erledigt werden kann. Nehmen wir an, es gibt ein Objekt Bitmap, dass mit ++ die Transparenz erhöht. Nun haben wir eine 2MPix Bitmap, das sind 8MB Daten.
Rufst Du ++i auf, wird die Bitmap verändert und stellt auch das Ergebnis dar. Rufst Du i++ auf, wird ein Temporäres Objekt erzeugt, 8MB Daten kopiert und modifiziert, um dann wieder verworfen zu werden.++i spart - in der Regel - das Erzeugen und Zerstören eines temporären Objektes und die Verwendung von ++i ist definitiv kein Performance-Mythos.
Cpt. Nukem schrieb:
Was bringt sowas wriklich? Gibts dazu wirklich Beweise oder sind das nur Behauptungen? Bei manchen neuen Anwendungen fragt man sich schon, was da manchmal so lange braucht, aber liegt das wirklich an OOP?
OOP ist eine Technik, wenn Du OOP brauchst, um ein Problem zu lösen, brauchst Du OOP. Egal ob Du OOP in C++ oder C verwendest. OOP ist keine kostenlose Technik, sie verbraucht Rechenzyklen und geht damit auf die Performance. Das ist vergleichbar mit Arrays und Listen.
Arrays sind schneller, Listen sind eine Technik, die mehr Performance benötigt, aber Arrays eben flexibler macht. Obwohl es länger dauert, durch eine Liste zu iterieren als durch ein Array, ist es einfacher Elemente zu verschieben, hinzuzufügen oder zu entfernen.
Es gilt also zu entscheiden, wo die Schwerpunkte in Deinem Algorithmus liegen.Grundsätzlich OOP zu verwenden verlangsamt Programme unnötig. Da OOP in C aufwendig ist, wird man in C vermeiden OOP zu verwenden. Wenn man allerdings wirklich OOP benötigt, ist die übliche Implementierung in C++ allerdings recht flott und im großen Ganzen die schnellste Methode, um OOP Probleme allgemeingültig zu lösen.
-
Xin schrieb:
Cpt. Nukem schrieb:
Man liest ja hier öfters OOP ist langsamer als ohne OOP oder ++iter statt iter++.
Dazu vielleicht mal etwas Klartext:
int & int::operator ++() // ++i { value = value + 1; return this; } int int::operator ++( int ) // i++ { int temp = value; value = value + 1; return temp; }
Du siehst, die Postfix-Variante benötigt ein temporäres Objekt und hat daher mehr Aufwand.
Das Objekt ist in diesem Fall (int) kein erwähnenswertes Problem. Ergo auch kein Problem, da der Compiler das hier ausgleichen kann:int & int::operator ++() // ++i { value = value + 1; returncode = value; } int int::operator ++( int ) // i++ { returncode = value; value = value + 1; }
Hier werden Objekte kopiert, was bei Integers durch die CPU problemlos erledigt werden kann. Nehmen wir an, es gibt ein Objekt Bitmap, dass mit ++ die Transparenz erhöht. Nun haben wir eine 2MPix Bitmap, das sind 8MB Daten.
Rufst Du ++i auf, wird die Bitmap verändert und stellt auch das Ergebnis dar. Rufst Du i++ auf, wird ein Temporäres Objekt erzeugt, 8MB Daten kopiert und modifiziert, um dann wieder verworfen zu werden.++i spart - in der Regel - das Erzeugen und Zerstören eines temporären Objektes und die Verwendung von ++i ist definitiv kein Performance-Mythos.
Das stimmt soweit natürlich alles.
Xin schrieb:
Cpt. Nukem schrieb:
Was bringt sowas wriklich? Gibts dazu wirklich Beweise oder sind das nur Behauptungen? Bei manchen neuen Anwendungen fragt man sich schon, was da manchmal so lange braucht, aber liegt das wirklich an OOP?
OOP ist eine Technik, wenn Du OOP brauchst, um ein Problem zu lösen, brauchst Du OOP. Egal ob Du OOP in C++ oder C verwendest. OOP ist keine kostenlose Technik, sie verbraucht Rechenzyklen und geht damit auf die Performance. Das ist vergleichbar mit Arrays und Listen.
Arrays sind schneller, Listen sind eine Technik, die mehr Performance benötigt, aber Arrays eben flexibler macht. Obwohl es länger dauert, durch eine Liste zu iterieren als durch ein Array, ist es einfacher Elemente zu verschieben, hinzuzufügen oder zu entfernen.
Es gilt also zu entscheiden, wo die Schwerpunkte in Deinem Algorithmus liegen.Grundsätzlich OOP zu verwenden verlangsamt Programme unnötig. Da OOP in C aufwendig ist, wird man in C vermeiden OOP zu verwenden. Wenn man allerdings wirklich OOP benötigt, ist die übliche Implementierung in C++ allerdings recht flott und im großen Ganzen die schnellste Methode, um OOP Probleme allgemeingültig zu lösen.
Wie kommst du auf diesen Unfug? Das hätte ich von dir nicht erwartet.
-
Mr. N schrieb:
Wie kommst du auf diesen Unfug? Das hätte ich von dir nicht erwartet.
weil OOP ist evil...
Irgendwann werden die Leute schon verstehen dass ob OOP oder sonstwas - nur eine Art Probleme zu lösen ist. Man kann Probleme auf viele Arten lösen - mal mag die eine eleganter sein als die andere - aber mit Performance hat das erstmal nichts zu tun.
Bestes Beispiel sind virtuelle Funktionen. Klar kosten sie mehr als eine normale Funktion - aber dafür hat man eine Fallunterscheidung die man ja nicht einfach ignorieren kann. Egal wie ich das Problem nun angehe - ich brauche diese Fallunterscheidung. Sei es eine Jump Table, ein if, ein switch, virtuelle Funktionen oder höher stehende Magie - ich habe kosten für diese Unterscheidung.
-
asc schrieb:
Kenner des Codes schrieb:
C ist schneller als C++. Ende.
Von der Reinen Aussage her ja, genauso wie Assembler schneller als C ist.
Aber in der Praxis gibt es mehr als nur einen reinen Sprachvergleich:
a) Ist der Code noch so gut überschaubar das sich nicht Fehler und Codeduplikate sowie Performancefallen mehren? Zumeist liegt der Vorteil von C++ gegenüber C an der besseren Strukturierung (Wobei vieles an Programmiererfahrung liegt).
**
b) Der Code mag noch so schnell sein, die Umsetzung muss in der Regel gegen einen Gewissen Zeitdruck erfolgen. Performance ist nicht Alles, sonst würde es keine Sprachen wie Java und C# geben. Man muss immer gewisse Kompromisse eingehen.**cu André
LOL das mag ja richtig sein was du unter b) gesagt hast, aber ging es grad net um die reine Performance .
-
Xin schrieb:
Cpt. Nukem schrieb:
Was bringt sowas wriklich? Gibts dazu wirklich Beweise oder sind das nur Behauptungen? Bei manchen neuen Anwendungen fragt man sich schon, was da manchmal so lange braucht, aber liegt das wirklich an OOP?
OOP ist eine Technik, wenn Du OOP brauchst, um ein Problem zu lösen, brauchst Du OOP. Egal ob Du OOP in C++ oder C verwendest. OOP ist keine kostenlose Technik, sie verbraucht Rechenzyklen und geht damit auf die Performance. Das ist vergleichbar mit Arrays und Listen.
Arrays sind schneller, Listen sind eine Technik, die mehr Performance benötigt, aber Arrays eben flexibler macht. Obwohl es länger dauert, durch eine Liste zu iterieren als durch ein Array, ist es einfacher Elemente zu verschieben, hinzuzufügen oder zu entfernen.
Es gilt also zu entscheiden, wo die Schwerpunkte in Deinem Algorithmus liegen.Grundsätzlich OOP zu verwenden verlangsamt Programme unnötig. Da OOP in C aufwendig ist, wird man in C vermeiden OOP zu verwenden. Wenn man allerdings wirklich OOP benötigt, ist die übliche Implementierung in C++ allerdings recht flott und im großen Ganzen die schnellste Methode, um OOP Probleme allgemeingültig zu lösen.
Ich versteh zwar den Zusammenhang nicht, dass etwas langsamer ist, weil es eine Technik ist. Aber es stimmt natürlich, dass es mehr Zeit braucht ein Objekt zu erzeugen und damit eine Funktion aufzurufen, als direkt eine Funktion aufzurufen.
Man kann natürlich noch weiter gehen und sagen, dass Funktionsaufrufe Zeit brauchen, darum sollte man alles direkt hinschreiben. Macht wohl keiner.
Aber was macht OOP in der Praxis aus? Viel Prozent der Zeit gehen für sowas drauf? 30, 3, 0.3 oder noch weniger? Gibts dazu eine verlässliche Quelle?