Schnellere Klassen-Methode



  • Hallo!

    Ich bau mir grad eine kleine Vektor Klasse zusammen. Momentan stehe ich jedoch vor der Frage, wie ich Funktionen die ich auf Vektoren anwende, am besten umsetze. Ich habe grad zwei Ansätze:

    struct vec3
    {
    	float x;
    	float y;
    	float z;
    
    	// Variante 1
    	inline static float Dot1(
    		const vec3& v0
    		const vec3& v1
    		)
    	{
    		return v0.x*v1.x + v0.y*v1.y + v0.z*v1.z;
    	}
    
    	// Variante 2
    	inline float dot2(
    		const vec3& v
    		)
    	{
    		return x*v1.x + y*v1.y + z*v1.z;
    	}
    };
    

    Als relativ Unwissender vermute ich, dass die 2te Variante schneller ist, als die erste, da ich der Methode somit nur 1ne Referenz übergeben muss, anstatt 3. Da mir jedoch in letzter Zeit des öfteren aufgefallen ist, dass C++ sehr trügerisch ist, würd ich gern von einem "Experten" wissen, ob meine Vermutung nun stimmt, oder nicht.



  • 1. Die inlines sind überflüssig.
    2. Bei dot2(..) werden auch 2 Argumente übergeben - an erster Stelle wird implizit this übergeben.



  • Unwissssender schrieb:

    Als relativ Unwissender vermute ich, dass die 2te Variante schneller ist, als die erste,

    Als relativ Unwissendem sollte es dir erstmal egal sein, ob die eine Variante einen oder zwei für dich nicht zu unterscheidende extrem kurze Augenblicke braucht. Der Sinn der Methoden sollte dir zuerst am Herzen liegen.

    da ich der Methode somit nur 1ne Referenz übergeben muss, anstatt 3.

    anstatt 2.

    Da mir jedoch in letzter Zeit des öfteren aufgefallen ist, dass C++ sehr trügerisch ist,

    Trügerisch in wiefern?

    Der Unterschied zwischen deinen Methoden ist neben dem nicht wirklich relavanten (und nach Compileroptimierungen nicht mehr vorhandenen) Geschwindigkeitsunterschied, dass dot2 das Produkt von dem gegebenen Vektor mit dem Parameter berechnet, während in Dot1 irgendein Vektor das Produkt zweier anderer Vektoren berechnet, mit denen er garnichts zu tun hat. Ziemlich sinnfrei also.



  • Der this-Zeiger muss (versteckt) mit übergeben werden, so gerechnet kommt also das gleiche raus.

    Es kann trotzdem Unterschiede geben, falls z.B. this in einem Register übergeben wird und Parameter auf dem Stack.

    Davon abgesehen: Wenn die Funktionen inline expandiert werden, muss überhaupt nichts übergeben werden.

    Als "relativ Unwissender" solltest du Abstand von solchen Überlegungen nehmen. Mach das, was am einfachsten zu implementieren, zu verstehen und zu benutzen ist. Das ist meistens auch das richtige.



  • Bashar schrieb:

    Als "relativ Unwissender" solltest du Abstand von solchen Überlegungen nehmen. Mach das, was am einfachsten zu implementieren, zu verstehen und zu benutzen ist. Das ist meistens auch das richtige.

    Dem kann ich nur zustimmen.

    Ich würde übrigens weder Variante 1 noch 2 nehmen. Nicht alles muss in Klassen gestopft werden, in C++ sind freie Funktionen nicht selten die bessere Wahl.

    float dot(vec3 lhs, vec3 rhs);
    

    Jedenfalls finde ich Variante 2 grauenhaft, da a.dot(b) eine Asymmetrie der Argumente suggeriert: Ist a.dot(b) das Gleiche wie b.dot(a) ? Wird eventuell sogar das Objekt verändert? Schlimmer ist, dass die Asymmetrie auch tatsächlich entsteht, weil z.B. implizite Konvertierungen nur noch auf dem rechten Objekt anwendbar sind.

    Kopie oder Const-Referenz sollte auch keinen grossen Unterschied machen. Bei Pass By Value kopierst du halt mehr, aber dafür fällt die Dereferenzierung weg. Möglicherweise wird das aber aufs Gleiche optimiert.


Log in to reply