Variablen in eigenem Projekt private machen?
-
flammenvogel schrieb:
Lass dich von keinem hier von der Aussage beeindrucken "Das ist schlechter Stil" oder "das macht man nicht". Wie so oft führen viele Wege nach Rom. Solange es keinen Performancetechnischen Unterschied macht kanst du auch noch ganz andere Sachen machen.
schlechter stil wird durchaus zum problem sobald im team gearbeitet wird
aber zum thema möcht ich noch zwei punkte beisteuern
1. wenn es vollkommen egal ist welchen wert die mausposition hat könntest dus natürlich auch public machen
in einer set funktion hast du aber noch die möglichkeit die position zu kontolliern und abzuändern2. falls irgendwann ungültige werte gesetzt werden, kannst du in ner set funktion leichter per bedingtem breakpoint prüfen von wem der wert gesetzt wird.
falls die variable public is müsstest du halt einen breakpoint auf die speicheradresse setzen
-
"Das ist schlechter Stil" oder "das macht man nicht".
Hier wurde nicht in diesem Sinne argumentiert, sondern vielfach klare und nachvollziehbare Argumente vorgebracht. Hat man bessere Argumente, kann man diese ja nennen. Bisher habe ich jedoch noch kein stichhaltiges Argument gelesen, um eine Member-Variable public zu gestalten. Auch das Performance-Argument sticht nicht.
-
Erhard Henkes schrieb:
"Das ist schlechter Stil" oder "das macht man nicht".
Hier wurde nicht in diesem Sinne argumentiert, sondern vielfach klare und nachvollziehbare Argumente vorgebracht. Hat man bessere Argumente, kann man diese ja nennen. Bisher habe ich jedoch noch kein stichhaltiges Argument gelesen, um eine Member-Variable public zu gestalten. Auch das Performance-Argument sticht nicht.
Hey, ich sagte ja schon, ihr habt recht
Ehrlich gesagt hab ich mich hier auf einige Bereiche der Grafikprogrammierung bezogen, da ich vor ein paar Wochen genau dieses Problem hatte, und mich entschieden hab, es public zu machen. Aus dem Einfachen Grund weil ich in einer Inneren Schleife Zugriff auf mehrere Variablen einer Klasse brauchte.
-
Hey, ich sagte ja schon, ihr habt recht.
o.k.
Teste doch mal genau dieses Beispiel mit get-Funktionen (inline), damit du siehst, dass es wirklich kein Nachteil ist.
Aber den Schwerpunkt sollte man im "information hiding" sehen.
-
Ui hier hat sich ja einiges getan.
Es ist nun wirklich so das die variablen oft benutzt und verändert werden. Ich würde sagen das Projekt ist sogar relativ groß, ich bin noch fast ganz am Anfang, habe aber schon ~2400 Hardcodezeilen (code counter sei dank).
Wie sieht das nun mit der Performance aus?cd9000 schrieb:
randa schrieb:
Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Nein.
operator void schrieb:
randa schrieb:
Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Wozu gibt es inline?
groovemaster2002 schrieb:
randa schrieb:
Ich würde mal einen anderen Punkt auch reinbringen: Wenn deine Get/Set Meothoden wikrlich sehr oft aufgerufen werden, wäre es auf Preformancesicht besser, du würdest die Public machen und auf Mehtoden verzichten.
Da es generell eine kluge Idee ist, solch kleine Funktionen inline zu machen, bekommst du auch keine Performance Penalty.
Bin ich denn jetzt mit inline aus dem schneider?
-
Bin ich denn jetzt mit inline aus dem schneider?
... ansonsten sollst du deinen Compiler wegwerfen.
Miss es doch einfach selbst nach.
-
Immer dieses "miss es doch nach".
Ich will aber nicht empirisch herausfinden ob es so ist, sondern ich will wissen ob es so ist
-
ratlos439857 schrieb:
Ich will aber nicht empirisch herausfinden ob es so ist, sondern ich will wissen ob es so ist
Das wurde jetzt in mindestens 5 Postings zum Ausdruck gebracht. Der Vorschlag es zu messen sollte nur dich dazu bringen, es auch zu glauben. Wenn du es nicht glaubst kannst du dir ja den Assemblercode anschauen.
-
Das Stichwort inline bedeutet IMHO das überall wo die Funktion auftaucht, der Kompiler die Stelle vorm kompilen durch den Code der Funktion erstetzt.
Möglichkeit A:
Du läst die Funktion so wie sie ist (ohne inline).
In diesem Fall muss später das Programm immer, bei aufruf der Funktion, zur Definition der Funkton springen. Das ist dann meistens damit Funktion das sich das Programm einen vermerkt macht wo es stehen geblieben ist, vor aufruf der Funktion. Das kostet etwas Zeit.Möglichkeit B:
Du machst die kurzen oft benötigten Funktionen inline.
Dann erstetzt der Kompiler die Funktionsaufrufe im Quelltext durch den Code der Funktion. (so wie das bei #define ist). Bei kleinen Funktionen die oft aufgerufen werden spart man sich den Vermerk, das erhöht die Performance. Bei längern oft aufgerufen Funktionen, bläht sich der Quelltext dadurch aber sehr auf. Da IMHO (ich bin nicht ganz sicher!) das komplette Programm vor ausführung in den Hauptspeicher eingelese werden muss, kann es in diesem Fall auch Performance Verlust geben.Da ich jetzt den einzel Fall nicht kenne kann ich dir nicht sagen ob das schneller ist oder nicht.
PS: Korriegrt mich wenn es B Fehler gibt!
-
flammenvogel schrieb:
Du machst die kurzen oft benötigten Funktionen inline.
Dann erstetzt der Kompiler die Funktionsaufrufe im Quelltext durch den Code der Funktion. (so wie das bei #define ist). Bei kleinen Funktionen die oft aufgerufen werden spart man sich den Vermerk, das erhöht die Performance. Bei längern oft aufgerufen Funktionen, bläht sich der Quelltext dadurch aber sehr auf. Da IMHO (ich bin nicht ganz sicher!) das komplette Programm vor ausführung in den Hauptspeicher eingelese werden muss, kann es in diesem Fall auch Performance Verlust geben.IMHO ist das eher nicht der Fall, dass die komplette exe in den RAM geladen wird. Gegenbeispiel: 3dmark03.exe. Der Installer ist eine einzige, riesige exe-Datei. Trotzdem startet der Installer sofort, ohne komplett im Speicher zu landen. Einige Spiele arbeiten ähnlich.
inline-Funktionen machen allerhöchstens ein paar kb aus (und das ist schon viel). Eine Funktion, die ein paar Berechnungen durchführt, hat vielleicht 30-50 Bytes. Selbst wenn die 20 Mal inline aufgerufen wird, macht das noch kein Kilobyte aus.
Um den Speicherverbrauch sollte man sich bei inline heutzutage wirklich am wenigsten Gedanken machen.edit: Falls man einen On-Access-Viren-Scanner aktiv hat (
) merkt man manchmal, was es heißt, wenn die komplette exe in den Speicher geladen wird.
-
Damit wäre dann wohl geklärt, dass Member-Variablen nicht public sein sollen. public data bringen keinen Performance-Vorteil, keinen bedeutenden Speicher-Vorteil, dafür aber eine Verletzung des wichtigsten Prinzips der OOP.
-
flammenvogel schrieb:
Wenn du die Klasse nicht benutzt kanst du die Variabel ruhgen Gewissens public machen. Das Konzept ist für den normalsterblichen Hobbyprogrammierer sowieso etwas überdiemensioniert. Ich würde mal sagen wenn du weniger als 200 Zeilen Code (ohne die Klasse!) hast kannst du dir das Konzept schenken in dem Fall spielts wirklich keine Geige.
Wenn du so an die Sache rangehst, denk ich, dass C++ generell dafür überdimensioniert ist. Dann tut's C genauso. Es macht keinen Unterschied ob dein Programm 200 oder 200.000 Zeilen Code hat. Gewisse Sprachprinzipien sollte man grundsätzlich einhalten.
flammenvogel schrieb:
Du machst die kurzen oft benötigten Funktionen inline.
Dann erstetzt der Kompiler die Funktionsaufrufe im Quelltext durch den Code der Funktion. (so wie das bei #define ist). Bei kleinen Funktionen die oft aufgerufen werden spart man sich den Vermerk, das erhöht die Performance. Bei längern oft aufgerufen Funktionen, bläht sich der Quelltext dadurch aber sehr auf. Da IMHO (ich bin nicht ganz sicher!) das komplette Programm vor ausführung in den Hauptspeicher eingelese werden muss, kann es in diesem Fall auch Performance Verlust geben.Du solltest nicht vergessen, dass inline nur ein Hinweis an den Compiler ist. Ob er wirklich inlined ist ganz allein seine Entscheidung. Bei Debug Builds müssen selbst kleine Funktionen nicht inlined werden, genauso verhält es sich im Release Build, falls eine Funktion zu gross ist.
-
Immer dieses "miss es doch nach".
Ich will aber nicht empirisch herausfinden ob es so ist, sondern ich will wissen ob es so istAlso gut, wir messen zusammen.
Versuchsaufbau: Dev-C++ 4.9.9.0, Sourcecode:
// Zeitmessung #include <iostream> #include <ctime> // clock_t, clock(), ... #include <conio.h> #include <cmath> using namespace std; class X { public: int a_; inline int getA() const {return a_;} }; int main() { X x; const int NMAX = 15; int max; cout << "Anzahl Schleifendurchlaeufe? "; cin >> max; clock_t t1,t2; double ts, tm=0; double a; cout << endl; for(int n=0; n<NMAX; ++n) { t1 = clock(); // Start for( int i=0; i<max;i++) { a = x.a_; //zu messende Aktion 1 } t2 = clock(); // Ende ts = (t2-t1)/static_cast<float>(CLOCKS_PER_SEC); // Zeit in Sekunden. cout << "Zeit Aktion 1: " << ts << " sec" << endl; tm += ts; // Das ist das Gleiche wie tm = tm + ts } tm/=NMAX; // Das ist das Gleiche wie tm = tm / NMAX cout << "Durchschnitts-Zeit bei Aktion 1: " << tm << " sec" << endl; tm=0; cout << endl; for(int n=0; n<NMAX; ++n) { t1 = clock(); for( int i=0; i<max;i++) { a = x.getA(); //zu messende Aktion 2 } t2 = clock(); ts = (t2-t1)/static_cast<float>(CLOCKS_PER_SEC); cout << "Zeit bei Aktion 2: " << ts << " sec" << endl; tm += ts; } tm/=NMAX; cout << "Durchschnitts-Zeit bei Aktion 2: " << tm << " sec" << endl; getch(); }
Erster Versuch: ohne Optimierung!
Anzahl Schleifendurchlaeufe? 30000000
Zeit Aktion 1: 0.13 sec
Zeit Aktion 1: 0.12 sec
Zeit Aktion 1: 0.14 sec
Zeit Aktion 1: 0.1 sec
Zeit Aktion 1: 0.12 sec
Zeit Aktion 1: 0.101 sec
Zeit Aktion 1: 0.12 sec
Zeit Aktion 1: 0.12 sec
Zeit Aktion 1: 0.13 sec
Zeit Aktion 1: 0.12 sec
Zeit Aktion 1: 0.131 sec
Zeit Aktion 1: 0.13 sec
Zeit Aktion 1: 0.13 sec
Zeit Aktion 1: 0.12 sec
Zeit Aktion 1: 0.13 sec
Durchschnitts-Zeit bei Aktion 1: 0.1228 secZeit bei Aktion 2: 0.291 sec
Zeit bei Aktion 2: 0.3 sec
Zeit bei Aktion 2: 0.301 sec
Zeit bei Aktion 2: 0.31 sec
Zeit bei Aktion 2: 0.29 sec
Zeit bei Aktion 2: 0.281 sec
Zeit bei Aktion 2: 0.29 sec
Zeit bei Aktion 2: 0.301 sec
Zeit bei Aktion 2: 0.3 sec
Zeit bei Aktion 2: 0.301 sec
Zeit bei Aktion 2: 0.3 sec
Zeit bei Aktion 2: 0.3 sec
Zeit bei Aktion 2: 0.301 sec
Zeit bei Aktion 2: 0.29 sec
Zeit bei Aktion 2: 0.291 sec
Durchschnitts-Zeit bei Aktion 2: 0.296467 secZweiter Versuch: mit bester Optimierung!
Anzahl Schleifendurchlaeufe? 30000000
Zeit Aktion 1: 0.05 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.05 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.05 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.05 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.051 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.04 sec
Zeit Aktion 1: 0.05 sec
Zeit Aktion 1: 0.04 sec
Durchschnitts-Zeit bei Aktion 1: 0.0440667 secZeit bei Aktion 2: 0.05 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.05 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.05 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.05 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.051 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.04 sec
Zeit bei Aktion 2: 0.04 sec
Durchschnitts-Zeit bei Aktion 2: 0.0434 secMan sieht, dass der Zugriff über get-Funktion weniger performant ist, dies sich aber durch Optimierung leicht ausgleichen lässt.
Vielleicht kann jemand, der sich da besser auskennt, erklären, wie ein guter Compiler den Nachteil der get-Funktion genau ausgleicht.
-
Immer dieses "miss es doch nach".
Ich will aber nicht empirisch herausfinden ob es so ist, sondern ich will wissen ob es so ist
Wenn man wissen will, ob es sich lohnt eine Funktion A inline zu machen (ob die Vorteile also die Nachteile überwiegen), dann hilft im Allgemeinen nur eins: Profilen, profilen, profilen. Am Besten mit Daten, die möglichst nah am durchschnittlichen Anwendungsszenario sind. Dazu startet man erstmal ohne inline und prüft dann wie oft die Funktion A aufgerufen wird und wieviel Zeit das Programm in der Funktion A verbringt (insgesamt und pro Aufruf). Sollte sich dabei herausstellen, dass die Funktion in den für die Performance relevanten 20% (oder 10 oder 15) des Programms liegt, dann kann man auch mal mit inline rumspielen.
Will man hingegen wissen, ob eine konkrete und als inline deklarierte Funktion A vom Compiler auch wirklich inline generiert wurde, dann muss man schlicht und einfach mal in den generierten Code schauen.
Das Stichwort inline bedeutet IMHO das überall wo die Funktion auftaucht, der Kompiler die Stelle vorm kompilen durch den Code der Funktion erstetzt.
Nein das bedeutet das Schlüsselwort nicht. Was das Schlüsselwort genau bedeutet wurde hier in diesem Forum bestimmt schon 1.6 Milliarden Mal ausführlich erklärt (die Zahl ist kaum übertrieben, da allein ich das Thema bestimmt 1.4 Milliarden Mal behandelt habe).
Ganz kurz:
* Inline ist eine Bitte kein Befehl. Man bittet den Compiler die Definition einer Funktion dort inline zu expandieren, wo diese Funktion aufgerufen wird. Dem Compiler steht es aber frei diese Bitte zu ignorieren.
Eine Funktion kann vom Compiler nur inline generiert werden, wenn er die Definition der Funktion sehen kann. Deshalb:
* Inline ändert die Definitionsbedingung einer Funktion von "Einmal pro Programm" auf "Einmal pro Übersetzungseinheit".
-
cd9000 schrieb:
...inline-Funktionen machen allerhöchstens ein paar kb aus (und das ist schon viel). Eine Funktion, die ein paar Berechnungen durchführt, hat vielleicht 30-50 Bytes. Selbst wenn die 20 Mal inline aufgerufen wird, macht das noch kein Kilobyte aus.
Um den Speicherverbrauch sollte man sich bei inline heutzutage wirklich am wenigsten Gedanken machen.hmm, schon plausibel. Doch hat der professionelle Programmierer kein Bestreben danach, so gut zu schreiben, dass sein Programm möglichst speichersparend + schnell ist?
Auch wenn das jetzt etwas überzogen ist, klingt deine Aussage für mich so ähnlich, wie wenn man sagen würde:
In 10 Jahren gibt's ein paar Teraherz und -byte, wozu noch "sauber", effizient programmieren? Ist doch ganz egal, wie das Programm geschrieben wird, die Hardware packt's in jedem Fall
Sehe ich das falsch? Sollte die Softwareanforderungen die Hardware doch noch übertreffen?@Erhard: Guter Beitrag
Fand' ich mal sehr anschaulich, dein Messbsp.Gruß
E-the-Real
-
Sollte die Softwareanforderungen die Hardware doch noch übertreffen?
Die Software wird sicher schneller langsamer werden als die Hardware schneller.
Die Hardware-Leistungsfähigkeit verdoppelt sich ca. alle 18 Monate. Das wird durch neuen Grafik-Softwareschnickschnack locker aufgebraucht.
Manche Aufgaben sind aber auch mathematisch so ausgelegt, dass man nur ganz mühsam voran kommt, z.B. beim Schachspielen mit dem Computer (bei jedem Halbzug ca. 20-30 neue Möglichkeiten). In den 80er Jahren hat ein Rechner weniger Züge als ein Mensch berechnen können. Heute schafft es ein Rechner in wenigen Minuten auf ca. 7-8 volle Züge voraus. Damit übersieht man keine "geniale" Mattkombination mehr. Strategisch (längere Sicht als 7-8 Züge) ist der Mensch noch überlegen. Koppelt man allerdings noch eine bewertete Datenbank mit allen gespielten Partien ab einer gewissen Leistungsklasse (> 2 Mio. Partien) ein, so ist der Rechner bereits ein Monster (Deep Blue besiegte damit Weltmeister). Ein normaler begabter Schachspieler (ELO ca. 2000) hat gegen Fritz 8 (von Chessbase) mit ca. ELO 2500 keine Chance mehr.
Das eigentliche Coden wird irgendwann auch der/die Rechner übernehmen, so dass der Mensch sich auf das optimale Design und die Entwicklung neuer Algorithmen konzentrieren kann.
-
ethereal schrieb:
cd9000 schrieb:
[Speicherverbrauch von inline-Funktionen vernachlässigbar]
hmm, schon plausibel. Doch hat der professionelle Programmierer kein Bestreben danach, so gut zu schreiben, dass sein Programm möglichst speichersparend + schnell ist?
Auch wenn das jetzt etwas überzogen ist, klingt deine Aussage für mich so ähnlich, wie wenn man sagen würde:
In 10 Jahren gibt's ein paar Teraherz und -byte, wozu noch "sauber", effizient programmieren? Ist doch ganz egal, wie das Programm geschrieben wird, die Hardware packt's in jedem Fall
Sehe ich das falsch? Sollte die Softwareanforderungen die Hardware doch noch übertreffen?Nein, so meinte ich das nicht. Man muss natürlich immer noch Wert auf sauberes Programmieren legen und den Speicherverbrauch im Auge behalten.
Nur ist der Speicherverbrauch von inline-Funktionen in den meisten Fällen vernachlässigbar. Wie hier schon mehrmals gepostet wurde, ist inline (u.a.) nur eine Bitte an den Compiler. Wenn der Compiler entscheidet, dass die Funktion zu groß ist, wird sie eben nicht inline kompiliert.Anders sieht es aber aus, wenn man z.B. irgendwelche Mikrocontroller mit C programmiert; dann muss man sich mehr Gedanken machen, welche Funktionen man inline deklariert und welche nicht. In einer solchen Umgebung spielt jedes kb eine Rolle. Wobei bei nicht-inline-Funktionen wiederum der Speicherverbrauch im Stack wächst.
-
Danke Leute, ihr seid echt die besten. Ich denke durch eure Hilfe bin ich ein großes Stück weiter gekommen.
Meine letzte Frage wäre wovon der Compiler es abhängig macht, ob er sich zu inline durchringt. Hängt das nur von der Größe einer Methode oder Funktion ab?
-
-ratlos-- schrieb:
Meine letzte Frage wäre wovon der Compiler es abhängig macht, ob er sich zu inline durchringt. Hängt das nur von der Größe einer Methode oder Funktion ab?
Das ist ein Betriebsgeheimnis des Compilers. es hängt ziemlich sicher von der Größe ab, aber IMHO auch von den aufgerufenen Funktionen (Rekursion etwa verhindert inlining).