Gibt es sowas wie <?> unter C++?



  • Rock Lobster schrieb:

    ...Nun moechte ich aber von manchen Funktionen aus ein Polygon beliebiger Groesse zurueckgeben, ...

    Warum nicht wieder ein Funktionstemplate? Dann muss allerdings der Aufrufer die Dimension schon wissen (und sei es nur implizit).

    template <int DIM>
    Polygon<DIM>* f(Polygon<DIM> const& dummy);
    
    template <int DIM>
    Polygon<DIM>* f(int DIM) { return f(Polygon<DIM>); }
    

    Gruß,

    Simon2.



  • Ich haette vielleicht nicht "Programm" sondern "Vorgang" sagen sollen. Dieser Vorgang dauert im ersten Schritt sehr lang, es kommen danach noch ein paar Schritte die weniger lange dauern. Und der Vorgang kommt in meinem jetzigen "Programm" nur einmal vor, aber spaeter soll er immer wieder vorkommen koennen.

    Nachgemessen habe ich auch. Es kommen Daten uebers Netzwerk, und die CPU ist auf Voll-Last, das Netzwerk aber nicht. Also ist wohl davon auszugehen, dass in meinem Code zu viel passiert, und aus diesem Grund waere es sinnvoll, dort ein paar Dinge zu aendern. Da nun in jedem einzelnen Quad-Konstruktor jedoch ein unnoetiges "new" gemacht wird, waere das zumindest mal ein erster Anhaltspunkt.

    Ich habe mich gerade mit einem Kollegen unterhalten und ihm auch die Version mit der gemeinsamen IPolygon-Basisklasse vorgeschlagen (hatte sogar schon angefangen zu implementieren), er meinte jedoch, ich soll auf OOP in dem Fall verzichten, weil durch virtuelle Funktionen auch wieder unnoetig Overhead entsteht, der bei solch einer simplen Extrem-Basis-Klasse wie es ein Quad nunmal ist einfach nicht sein muss. Das war der Grund, warum ich sagte, dass ich nun wohl doch lieber eine voellig eigene, OOP-freie Implementierung einer Quad-Klasse bevorzugen wuerde. Hat aber nix mit beratungsresistent zu tun.



  • @ Simon2: Vielen Dank, auf diese Idee bin ich bisher nicht gekommen. Jedoch denke ich, dass auch das in meinem Anwendungsfall nicht sinnvoll sein wird (da man vorher nicht weiss, wie viele Punkte das Polygon dann haben wird). Mir ist nun auch klar warum das mit Templates nicht funktionieren kann. Trotzdem danke fuer den Hinweis, vielleicht kann ich das mal an einer anderen Stelle gut gebrauchen.



  • CPU ... Volllast ... Netzwerk nicht ... erster Anhaltspunkt ...

    Mit Nachmessen meine ich eine Profiler zu benutzen und genau zu schauen, wo viel Rechenleistung verbraten wird und nicht aufs geradewohl irgendwas zu optimieren.

    Quad-Konstruktor jedoch ein unnoetiges "new"

    Und es wurde gezeigt, wie das zu beheben ist, mit OOP. Ausserdem waere dann ein Objektpool wahrscheinlich angebrachter.

    ich soll auf OOP in dem Fall verzichten, weil durch virtuelle Funktionen auch wieder unnoetig Overhead entsteht

    in jedem Fall ... Hast du ihn auch gefragt, aus was der Overhead besteht und wieviel Zeit er kosten wird? Es ist eine zusaetzlich Dereferenzierung eines Zeigers. Also verdammt billig.

    Ich empfehle dir die Buecher von Scott Meyers: "Effektiv C++ programmieren" und "Mehr effektiv C++ programmieren".



  • Simon2 schrieb:

    template <int DIM>
    Polygon<DIM>* f(Polygon<DIM> const& dummy);
    
    template <int DIM>
    Polygon<DIM>* f(int DIM) { return f(Polygon<DIM>); }
    

    Ich bezweifle dass das funktioniert, denn erstens hast du für zwei verschiedene Identifyer denselben Bezeichner gewählt (einmal den Templateparameter, einmal den Funktionsparameter), zweitens wird erst zur Laufzeit entschieden, welches Argument der Funktion übergeben wird, der Templateparameter muss aber schon zur Laufzeit feststehen.
    Das Ganze müsste daher eher mit einer Art Int2Type als Funktionsargument geschehen:

    template <int DIM>
    Polygon<DIM>* f(Int2Type<DIM> /*dummy*/);
    


  • pumuckl schrieb:

    ...Ich bezweifle dass das funktioniert, ...

    Sollte auch eher eine Ideenskizze sein (hätte ich wohl besser hingeschrieben).
    Außerdem war die Idee zur 2. Funktion eher ein "Spontanblitz" .... was wohl (wie so oft) unter die Kategorie "Der Erste aber nicht der Beste" fällt 😉

    Deine Kritikpunkte zielen im Wesentlichen auf mein zweites template ab, oder?...

    Gruß,

    Simon2.



  • Rock Lobster schrieb:

    ...die CPU ist auf Voll-Last...

    Das ist an sich ein gutes Zeichen.
    Die Frage ist eher, ob der Prozess insgesamt zu lange dauert ... und ob Deine ergriffenen Maßnahmen helfen.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Deine Kritikpunkte zielen im Wesentlichen auf mein zweites template ab, oder?...

    Jup.

    @Rock: wie schon gesagt wurde, und wie du auch richtig erkannt hast gibts zwei Möglichkeiten: die "Größe" (= Zahl der Ecken) jedes Polygons zur Compilezeit festlegen -> alles mit Templates, oder zur Laufzeit -> keine Templates, dafür dynamische Speicherverwaltung.



  • pumuckl schrieb:

    ...zwei Möglichkeiten: die "Größe" (= Zahl der Ecken) jedes Polygons zur Compilezeit festlegen -> alles mit Templates, oder zur Laufzeit -> keine Templates, dafür dynamische Speicherverwaltung.

    Plus die "Frickellösungen" (die bisweilen tatsächlich optimal sein können); z.B.:
    - eigene Speicherverwaltung
    - "feste templates"

    (Ideenskizze !!!)

    template <int DIM> struct Polygon { };
    
    template <typename T> T f(T const& dummy){ ... }
    
    int main() {
    //...
       if(irgendeinKriterium) {
          vector<Polygon<4> > myPolys(1000);
          myPoly[2] = f(myPoly[0]);
       }
       else {
          vector<Polygon<16> > myPolys(1000);
          myPoly[2] = f(myPoly[0]);
       }
    

    Nicht unbedingt schön und auch nur für kleine konkrete Zahlen anzuraten, aber bei recht aufwendigem f() kann das schon das geringere Übel sein....

    Gruß,

    Simon2



  • Rock Lobster schrieb:

    Ich moechte kein new im Konstruktor haben, damit die Werte moeglichst auf dem Stack abgelegt werden. Im Moment habe ich die new-Version und das ist einfach zu langsam (da extrem viele dieser Polygone instanziiert werden).

    Bist du sicher, dass das am new alleine liegt? Hat dir dein Profiler gesagt, dass die Funktion operator new den kritischen Teil der Zeit beansprucht?

    Ich würde eher raten, eine eigene Speicherverwaltung einzurichten, was in diesem Thread auch schon mehrmals erwähnt wurde. Dadurch kannst du dir vielen Speicher aufs Mal anfordern und den dann nach und nach verteilen. Aber der Stack eignet sich nicht für extrem viele oder grosse Objekte.



  • Hallo Christian,

    gib uns mal etwas mehr Code. Ich kann mir beim besten Willen nicht vorstellen,
    dass das wirklich das Problem in deinem Programm ist. Über wieviele Objekte
    innerhalb welches Zeitraums unterhalten wir uns denn?

    Gruß,
    CSpille



  • Im Moment ist der Server down, aber im Laufe des Tages werd ich nochmal testen und kann dann auch mehr zur Datenmenge und zur Laufzeit sagen. Ich habe keinen Profiler verwendet, aber innerhalb der Schleife passiert eigentlich auch nicht wesentlich mehr als das Anlegen von Objekten, und laut System Monitor ist die CPU mehr ausgelastet als das Netzwerk. Wie gesagt, ich werd heut nochmal ein bisschen rumprobieren, dann werd ich hier mehr dazu sagen koennen.



  • Rock Lobster schrieb:

    laut System Monitor ist die CPU mehr ausgelastet als das Netzwerk.

    Na und? Das heißt doch nur dass dein Rechner derweil nicht unnötig Zeit verschwendet indem er auf Antworten aus dem Netz wartet sondern die Zeit zum Rechnen nutzt.



  • Nur gibt es da nicht viel zu rechnen, daher wundert es mich schon sehr stark. Er muss nur Daten lesen und in eine Struktur schreiben und diese in einen vector packen. Naja ich werds austesten sobald der Server wieder laeuft, ich hoffe mal das wird heut noch was 😉


Anmelden zum Antworten