Wieviel Performance kostet die Objekt orientierte Programmierung?



  • rapso schrieb:

    vom assembler code (aus VS2003) her sah ich, dass einige ueberladene operatoren sich nicht dazu bringen lassen wollten ohne temp copy auszukommen, selbst nach dem inlinen, ansonsten sah der assembler ziemlich gleich aus.

    Kann man das mit dem &&-Opertator aus C++11 nicht schneller hinkriegen?



  • rapso schrieb:

    ich war an c++ und c dran, das resultat war, dass c++/oop (also z.b. vector klassen mit ueberladenen operatoren) ca 5% langsammer war als c/prozedural(z.b. vec_dot_3f(out,va,vb);).

    Ob da viel oop war? Oder bzw. ob C kein oop war? Hört sich auf jeden Fall so an, als ob es in beiden Fällen sehr ählicher Code war.



  • Shade Of Mine schrieb:

    hustbaer schrieb:

    otze schrieb:

    hustbaer schrieb:

    Welche Member werden denn über operator [] zugänglich gemacht?

    Elemente des vektor internen Felds? Oder sind Elemente eines Felds keine Member mehr?

    Natürlich nicht, waren sie auch nie.

    Sicher sind es Member. Nur eben keine die man kapseln müsste.

    Nö, es sind nie und werden nie Member.
    std::vector hat meist einfach drei Member, nen Zeiger und zwei size_t (allocated, used).
    Das sind die einzigen drei Member.

    Die verwalteten Elemente, sind eben Elemente, und zwar eines Arrays, auf das ganz zufälligerweise im Vektor ein Zeiger existiert.

    Das macht sie aber noch lange nicht zu membern.

    Davon abgesehen schliesse ich mir dem an was du geschrieben hast.
    (OK, dem meisten, ich finde das Beispiel nämlich immer noch schlecht, aber egal)

    BTW: bei std::array sieht die Sache schon wieder anders aus, da ist das Arrays selbst Member, dann kann man IMO auch sagen dass die Elemente des Arrays Member sind.



  • dot schrieb:

    Wieviel Performance kostet die Objekt orientierte Programmierung?

    Im Vergleich zu was?

    Das ergibt sich doch eindeutig aus der Frage.



  • &&- schrieb:

    rapso schrieb:

    vom assembler code (aus VS2003) her sah ich, dass einige ueberladene operatoren sich nicht dazu bringen lassen wollten ohne temp copy auszukommen, selbst nach dem inlinen, ansonsten sah der assembler ziemlich gleich aus.

    Kann man das mit dem &&-Opertator aus C++11 nicht schneller hinkriegen?

    Eher nicht. Und es ist kein Operator sondern ein Deklarator. Wenn Deine Vektor-Klasse direkt ein Array wrappt à la

    class vec3d {
      double xyz[3];
      :::
    };
    

    dann kannst du einfach move-technisch nichts besser machen als eine normale Kopie. Die Move-Operationen werden dann interessant, wenn der Zustand des Objekts nicht komplett in den sizeof(T) Bytes enthalten ist, sondern teilweise woanders gespeichert wird (wo auch immer) und die Klasse einen "natürlichen Nullzustand" besitzt (wie z.B. einen leeren Vektor oder ein unique_ptr, der auf nichts mehr zeigt).

    Wenn es um das Rechnen mit kleinen Vektoren/Matrizen und Geschwindigkeit geht, könnte man mal tvmet ausprobieren (tiny vector/matrix expression templates). Das stell ich mir zumindest sehr flott vor. Getestet habe ich das bisher nicht.



  • hustbaer schrieb:

    bei std::array sieht die Sache schon wieder anders aus, da ist das Arrays selbst Member, dann kann man IMO auch sagen dass die Elemente des Arrays Member sind.

    Es ist also für dich relevant ob ich new oder alloca verwende?
    Für mich sind das implementierungsdetails. zB gibt es bei Strings ja eine short-string-optimization die es ermöglich bei kurzen Strings ohne new auszukommen.

    Für mich ist die Implementierung der Klasse eher nebensächlich. Ob ich den Speicher mit einem array allokiere, alloca verwende oder new - das Konzept ist Speicherbeschaffung. Wie die stattfindet ist ein Implementierungsdetail.

    Dass std::array zB die Sachen in einem array hält ist für mich nur ein Detail. std::array wäre genauso OK wenn es die Sachen dynamisch allokiert. uU macht es sogar Sinn std::array zu spezialisieren und bei großen Arrays hier dynamisch zu allokieren...

    Was wäre dann? Member oder nicht member?



  • Shade,
    mich interessiert die Diskussion schon lange nicht mehr.
    Wenn ihr meint so tun zu müssen, als wüsstet ihr nicht was Member sind, OK.
    Wenn ihr meint so tun zu müssen, als wüsstet ihr nicht was ich mit meiner Kritik gemeint habe, auch OK.

    Macht halt.

    Bis demnächst in einem anderen Thread.



  • hmmmmm schrieb:

    rapso schrieb:

    ich war an c++ und c dran, das resultat war, dass c++/oop (also z.b. vector klassen mit ueberladenen operatoren) ca 5% langsammer war als c/prozedural(z.b. vec_dot_3f(out,va,vb);).

    Ob da viel oop war? Oder bzw. ob C kein oop war? Hört sich auf jeden Fall so an, als ob es in beiden Fällen sehr ählicher Code war.

    es war natuerlich kein klassengeruest usw. vorhanden, je mehr man das ausgebaut haette, desto mehr haette die vergleichbarkeit gelitten, somit ist das natuerlich auch kein kompletter c vs c++ vergleich, sollte es ja auch nicht werden.
    die frage war schlicht, ob es egal ist welche sprache und vorgehensweise man nimmt. es gab leute die sagten c/prozedural ist am schnellsten, weil man dort den fuer den compiler einfachsten code schreibt, es quasi high level assembler ist. auf der ganz anderen seite, c#/java das ganze program beim JIT kennt, es ist genau spezifiziert was auf was pointer usw. halten kann und ein compiler kann theoretisch genau wissen wann etwas aliast und wann nicht usw. und dadurch ist es moeglich besseren code zu generieren. auch wird das ueber files hinweg gemacht, waehrend c++ eigentlich nur innerhalb von translation unit optimiert wird (wobei VS2003 afaik, link time code generation eingefuehrt hatte und dadurch z.b. accessor funktionen geinlined werden, selbst wenn sie zur compiletime nicht zu sehen sind.)
    aber naja, die vorgaben waren schon relativ eng gesetzt, der ray/tri intersection algorithm war sogar als c code vorhanden, sodass es nur "portieren" war.
    ich hatte am anfang nicht erwartet, dass man einen unterschied messen koennen wird zwischen c/prozedural und c++/OOP (wie gesagt, nur vector klassen und simple stream in/out, was nicht zur messung gehoerte), es hat mich auch ueber jahre genervt 😡 bis ich den flipcode artikel ausnutzte.

    &&- schrieb:

    rapso schrieb:

    vom assembler code (aus VS2003) her sah ich, dass einige ueberladene operatoren sich nicht dazu bringen lassen wollten ohne temp copy auszukommen, selbst nach dem inlinen, ansonsten sah der assembler ziemlich gleich aus.

    Kann man das mit dem &&-Opertator aus C++11 nicht schneller hinkriegen?

    nein, wie kruemlk sagte, ist es eher fuer klassen mit referencen gedacht. um das zu optimieren wuerde man eher mojo benutzen. damit hatte ich angefangen, aber ueber ein paar hierarchieen hinweg wurden das ziemlich viele spezialisierte klassen werden. ich haette dafuer templates nutzen sollen, waere dann wohl bei der selben idee gelandet wie mein flipcode link.
    ich hatte damals ueberlegt ob ich mojo mit virtuellen operatoren mache und ob der compiler, wenn er den ganzen scope des mojo objektes kennt, den virtuellen function call durch einen direkten call bzw inlining loesen wuerde, aber wenn nichtmal RVO klappte, wollte ich die zeit nicht verschwenden.

    Psychologe22 schrieb:

    rapsos Posting uebersetzt: "Ich bin der geilste"

    suess dass du das ueber einen simplen erfahrungsbericht denkst :), fuehle mich geschmeichelt. :xmas1:



  • rapso schrieb:

    die frage war schlicht, ob es egal ist welche sprache und vorgehensweise man nimmt. es gab leute die sagten c/prozedural ist am schnellsten, weil man dort den fuer den compiler einfachsten code schreibt, es quasi high level assembler ist. auf der ganz anderen seite, c#/java das ganze program beim JIT kennt, es ist genau spezifiziert was auf was pointer usw. halten kann und ein compiler kann theoretisch genau wissen wann etwas aliast und wann nicht usw. und dadurch ist es moeglich besseren code zu generieren.

    Du hast vergessen, daß die JVM erstmal ganz viel Speicher vom Betriebssystem reserviert und das Java Programm allein dadurch schon schneller wird, weil somit viele häufige Betriebssystemaufrufe zur Speicherreservierung untersagt bleiben.

    Bei C++ muß die Rechnerzeit wegen jedem Popel an Speicheranforderung an das Betriebssystem abgegeben werden.
    Das sind viele häufige Prozesswechsel, die das ganze lahm machen.



  • Ekenner des Turbos schrieb:

    rapso schrieb:

    die frage war schlicht, ob es egal ist welche sprache und vorgehensweise man nimmt. es gab leute die sagten c/prozedural ist am schnellsten, weil man dort den fuer den compiler einfachsten code schreibt, es quasi high level assembler ist. auf der ganz anderen seite, c#/java das ganze program beim JIT kennt, es ist genau spezifiziert was auf was pointer usw. halten kann und ein compiler kann theoretisch genau wissen wann etwas aliast und wann nicht usw. und dadurch ist es moeglich besseren code zu generieren.

    Du hast vergessen, daß die JVM erstmal ganz viel Speicher vom Betriebssystem reserviert und das Java Programm allein dadurch schon schneller wird, weil somit viele häufige Betriebssystemaufrufe zur Speicherreservierung untersagt bleiben.

    Bei C++ muß die Rechnerzeit wegen jedem Popel an Speicheranforderung an das Betriebssystem abgegeben werden.
    Das sind viele häufige Prozesswechsel, die das ganze lahm machen.

    Tjo was soll man sagen, das ist einfach nur falsch.
    Wie der Heap implementiert ist, ist gänzlich der C++ Implementierung überlassen.
    Und ich kenne *keine*, die wegen jedem new/alloc das OS bemüht. Weil das nämlich, soweit hast du das richtig erkannt, total dämlich wäre.



  • Und die, die das letzte Stückchen Performance bei der Allokation haben wollen, verwenden ihren eigenen Allokator.


Anmelden zum Antworten