000
11.01.2006, 13:08 Uhr
~ADOOM
Gast
|
Hallo,
Folgende Problemstellung:
Code: |
class Integer { public: Integer(void); Integer(const int value); Integer(const Integer &var); ~Integer(void);
int operator + (Integer var) const; const Float sepp() const; // cast operatoren operator Float() const; // kein schreibfehler!!! Float pendant zu float wie Integer zu int private: int value; };
inline const Float Integer::sepp() const{ return value; }
inline int Integer::operator + (Integer var) const { return (this->value + var.value); }
//V 1 inline Integer::operator Float() const { const Float puff(value); return puff; } //V 2 (liefern beide das gleiche problem) inline Integer::operator Float() const { return value; }
|
Diese Klasse ist natuerlich noch groesser, was aber fuer die Frage belanglos ist. Main vollstaendig:
Code: |
int main(void) { Integer i(5); Integer j(6); Float f(3.7f); Char *c = new Char[100]; Double d(7.3849); Double dd(2.4233); utils::StopWatch *sw = new utils::StopWatch(); volatile int k=0; double time; ofstream file("inlineRTTI.csv", ios::out|ios::binary|ios::beg); int l=0; while (l < 100) { sw->reset(); sw->start(); while(k < 4000000000) { i += 1; i += j+2; i -= 3; i -= j+3; i *= 4; --i; i *= j+4; i /= 6; i /= j+5; ++i;
f += (Float) i; // <------ !!!!!!!!!!! operator Float() const f = f + 0.3f; f += 2.1f; f -= 1.2f; f /= 0.234f; c[0] = i+1; c[1] = i+2; if (i == j) f = 9.34f; else i = 345;
d /= dd; d *= dd; d += dd; d -= dd; //*/ ++k; }
time = sw->getTime(); file << time << ";" << endl; k=0; ++l; } file.close(); cout << i << j << c << f << d << dd; /* cout << "fertig" << endl; char fake[100]; cin >> fake;*/ return 0; }
|
Bei der makierten Zeile wird entsprechend der cast operator Aufgerufen. Dieser ist allerdings Inline definiert und sollte bei den entsprechenden optimierungseinstellungen ersetzt werden.
Ich benutze den VC++ 7, mit den einstellungen: Full Optimization (/Ox) Global Optimizations yes (/Og) Inline Function Expansion only _inline ODER any siutable Favor Fast Code
Die Inline Ersetzung sollte also an sein. Bei funktionen die eine Referenz auf sich selbst zurueckgeben und ansonsten nicht viel machen (siehe operator +) passiert dies auch, nur bei dem Cast operator bzw. bei Methoden die Beispielsweise in der Methodendefinition Objekte erstellen (siehe operator Float() const) wird immer noch ein call (sowohl Variante V1 als auch V2 und bei Integer::sepp()) ausgefuehrt:
; 50 : f += (Float) i;
lea ecx, DWORD PTR $T109043[esp+216] lea esi, DWORD PTR [edx+eax+1] push ecx lea ecx, DWORD PTR _i$[esp+220] mov DWORD PTR _i$[esp+220], esi call ??BInteger@@QBE?AVFloat@@XZ ; Integer::operator Float <-- das ist schlecht / langsam
; 50 : f += i.sepp(); lea ecx, DWORD PTR $T109036[esp+224] lea esi, DWORD PTR [edx+eax+1] push ecx lea ecx, DWORD PTR _i$[esp+228] mov DWORD PTR _i$[esp+228], esi call ?sepp@Integer@@QBE?BVFloat@@XZ ; Integer::sepp
gibt es eine Moeglichkeit die Methoden anders zu formulieren so dass entsprechend eine ersetzung anstatt eines sprunges vorgenommen wird / bzw gibt es eine Kompilereinstellung die dies bezweckt? (die Klasse soll in Float castbar sein (nicht float))
(der call macht die ganze sache ziemlich langsam)
thx for help |