Templates: Zur Laufzeit entscheiden?
-
ich hätte hier noch eine spezielle zusatzfrage die jetzt nicht in richtung performance zielt sondern auf die funktionsweise.
Mir ist nicht klar wie ich denn typ-abhängig die funktion aufrufen kann. Im Moment geschieht das bei mir so dass ich für jeden typ variablen anlege die ich brauchen werde und es werden halt nur die gesetzt in welchen typ-zweig gelaufen wird. Geht das nicht sauberer? So bleibt ja die Hälfte (bei 2 typen) an variablen immer auf Null z.B.:
//irgndwo in der main.cpp int* arr_int = NULL; float* arr_float = NULL; //jetzt wird herausgefunden welcher typ festliegt // z.B. durch einlesen eines files oder sonstwie das ist //unerheblich type = get_type(file); // jetzt kommt der if-zweig oder switch (man weiß ja nie welche typen noch // kommen) switch(type) { //t_int und t_float wurden über enum definiert case t_int: // wir sind im int-fall fülle_int_arr(arr_int); case t_float: // wir sind im float-fall fülle_float_arr(arr_float); } delete arr_int; delete arr_float;dnake
-
Habe ich etwas verpasst? Es ging doch eben noch um reell vs. komplex und nicht int vs. float.
Vielleicht solltest du doch etwas mehr Informationen rausrücken.
-
ob reell oder komplex oder int oder float ist doch für das Problem dass hier gerade gepostet habe irrelevant. Um konsistent zu bleiben hätte ich aber auch komplex benutzen können ja - sorry für die verwirrung. mehr infos sind für eine derartige frage zu viel overkill - es heißt doch immer minimalbeispiel..
-
Shade Of Mine schrieb:
unskilled schrieb:
google das mal: "premature optimization"
Will nur kurz anmerken dass das hier eine Designentscheidung ist an die man dann ewig gebunden ist. Da sollte man sich schon vorher gedanken machen...
Seh ich genauso - allerdings sind dann so ne Sätze kein Argument gegen irgendetwas:
"außerdem ist polymorphie von der performance zu langsam - zumindest hab ich das so bisher verstanden."
Wenn ich ne aufwendige, zeitintensive Fkt habe, dann ist die eben immer genauso zeitintensiv - vll ist sie immer 25 Taktzyklen früher fertig - aber wenn das so wichtig ist, sollte Performance auch keine Rolle spielen (sollte ja klar sein, dass 25 Taktzyklen entweder 0% sind, also egal oder wenns mehr ist, dann hat man au kein Performance-Problem)...
Kannst mich ja gern korrigieren, wenn ich damit falsch liege - aber denke nicht, dass es da so viel geben wird ;PMachts gut - ich tu mal so, als ob ich kein Kellerkind wäre und bin dann ma paar Stunden weg

-
Tippgeber schrieb:
Tachyon schrieb:
Tippgeber schrieb:
Klar, nennt sich Polymorphie, wundert mich, dass du das nicht kennst, das lernst man meist vor den Templates kennen.
Polymorphie macht hier aber keinen Sinn, da Du verschiedene Klassen hast, und immer noch unterscheiden musst, für welchen Zahlentyp Du einlesen willst.
Wieso nicht? Dafür gibt es Factories.
Und in der Factory wird nicht über eine Fallunterscheidung entschieden, ein Objekt welchen ADTs erstellt werden soll? Ich denke mal doch. Zumal reelle Zahlen und komplexe Zahlen aufgrund der unterschiedlichen Datentypen eigentlich eher nicht in den Bereich dessen Fallen, was Du mit Polymorphie meinst. Und für statische Polymorphie brauchts keine Factory.
-
Tachyon schrieb:
Tippgeber schrieb:
Tachyon schrieb:
Tippgeber schrieb:
Klar, nennt sich Polymorphie, wundert mich, dass du das nicht kennst, das lernst man meist vor den Templates kennen.
Polymorphie macht hier aber keinen Sinn, da Du verschiedene Klassen hast, und immer noch unterscheiden musst, für welchen Zahlentyp Du einlesen willst.
Wieso nicht? Dafür gibt es Factories.
Und in der Factory wird nicht über eine Fallunterscheidung entschieden, ein Objekt welchen ADTs erstellt werden soll? Ich denke mal doch. Zumal reelle Zahlen und komplexe Zahlen aufgrund der unterschiedlichen Datentypen eigentlich eher nicht in den Bereich dessen Fallen, was Du mit Polymorphie meinst. Und für statische Polymorphie brauchts keine Factory.
Gehen wir von verschiedenen Dingen aus? Ich dachte, dass es hier darum geht wie die Daten nach dem Einlesen gehandhabt werden.
Und das Einlesen an für sich sollte in der Factory geschehen bzw. dort so realisiert werden, dass eben (im Idealfall) nur dort diese Fallunterscheidung auftaucht.
-
Tippgeber schrieb:
...
Und dann? Dann hast Du immer noch verschiedene Typen. Da hilft Laufzeitpolymorphie nicht.
-
Tachyon schrieb:
Tippgeber schrieb:
...
Und dann? Dann hast Du immer noch verschiedene Typen. Da hilft Laufzeitpolymorphie nicht.
Ich denke dabei an
struct Number { /* ... */ }; struct Real : Number { /* ... */ }; struct Complex : Number { /* ... */ };Und du?
-
Tippgeber schrieb:
...
Ich würde jetzt eher an z.B.
floatundstd::complex<float>denken. Die Idee irgenwelche Wrapper dafür zu schreiben, halte ich nicht gerade für optimal.
Das hat ja schon fast was von den hier im Forum immer wieder auftauchenden "bool-Wrappern".
-
Tachyon schrieb:
Tippgeber schrieb:
...
Ich würde jetzt eher an z.B.
floatundstd::complex<float>denken. Die Idee irgenwelche Wrapper dafür zu schreiben, halte ich nicht gerade für optimal.
Das hat ja schon fast was von den hier im Forum immer wieder auftauchenden "bool-Wrappern".Du hast ja keinen zusätzlichen Speicherverbrauch durch diese Wrapper, aber ein Problem für das mir gerade keine schöne Lösung einfällt ist das Wrappen der Arrays, ein Number[] bzw. std::vector< Number > geht ja leider nicht. Von daher ist diese Lösung auch nicht wirklich ausgereift.
Aber ich bin sowieso der Meinung, dass man keine sinnvolle Lösung vorschlagen kann, so lange man nicht weiß wie komplex die Aufgabe wirklich ist.
-
Wirklich schön bringt man es eh nicht hin, wenn es darum geht, Speicherplatz zu sparen. Ein
void*ist oft etwa gleich gross wie einfloat, Boost.Variant ist auch nicht gerade platzsparend, und Polymorphie führt ebenfalls zu einem Overhead aufgrund des VPtrs.Von daher wäre ein generisches
std::complex<float>wohl am einfachsten, wenn der Typ zur Compilezeit noch nicht bekannt ist.
-
unskilled schrieb:
Seh ich genauso - allerdings sind dann so ne Sätze kein Argument gegen irgendetwas:
"außerdem ist polymorphie von der performance zu langsam - zumindest hab ich das so bisher verstanden."Das hat aber nichts mit premature optimization zu tun.
Diese Keule wird hier naemlich dauernd und bei jeder Performance Frage ausgepackt. Es ist natuerlich moeglich dass der OP nicht weiss wieviel dynamische Polymorphie kostet - es ist aber auch moeglich dass er es weiss.
Es gibt gute Gruende sich fuer statische Polymorphie zu entscheiden und einer davon ist eben Performance.
Prinzipiell immer dynamische zu nehmen ist premature pessimization...
Wenn ich ne aufwendige, zeitintensive Fkt habe, dann ist die eben immer genauso zeitintensiv - vll ist sie immer 25 Taktzyklen früher fertig - aber wenn das so wichtig ist, sollte Performance auch keine Rolle spielen (sollte ja klar sein, dass 25 Taktzyklen entweder 0% sind, also egal oder wenns mehr ist, dann hat man au kein Performance-Problem)...
Kannst mich ja gern korrigieren, wenn ich damit falsch liege - aber denke nicht, dass es da so viel geben wird ;PMal ueber den Tellerand sehen...
Statt 1 virtuelle Funktion koenntest du ja 100mio aufrufen. Dann ist es ploetzlich schon sehr relevant (vorallem wenn du ja durch dynamische polymorphie inlining verlierst)...
Also bitte bitte bitte, lasst die "premature optimization keule" einfach stecken. denn sie gilt bei design fragen nicht. es ist eine verallgemeinerung, dass man nicht in jeder funktion die man schreibt stundenlang microoptimierungen vornimmt.
aber sie gilt nicht fuer die design phase wo man naemlich sehr wohl etwaige performance pitfalls identifizieren muss. denn die regel besagt ja: optimiere nicht jetzt etwas, was du spaeter wenn du weisst dass es zu langsam ist nicht uU besser optimieren kannst.
nur wenn du ein falsches design nimmst, bist du erledigt - da es nichts gibt was du tun kannst.
-
Mein Fehler - wobei ich noch immer denke, dass (fast) jede Fkt (selbst wenn sie 1Mrd ma ausgeführt wird) ca. 0% der zeit für ihren Overhead braucht - es sei denn, sie braucht x parameter (diese hier braucht keine) und ist an sich sehr kurz -
fülle_array... klingt aber nicht danach - auch klingt es nicht so, als ob sie keine x Mal pro usec aufgerufen werden würde - und nach rekursion hört sich das auch nicht an...mehr infos sind für eine derartige frage zu viel overkill - es heißt doch immer minimalbeispiel
Es heißt minmal-Bsp - int main() {} is auch nen minimalbsp und lässt auch noch so ca. alle fragen offen...
Aber naja - der Thread ist mir ohnehin zu chaotisch, weil der OP nich so recht schreiben möchte, was er genau machen möchte, wozu er die Arrays dann benötigt, wo er die Daten herbekommt etc. - das es um Prozesskommunikation geht, ist bisher alles, was er geschrieben hat...
bb