Performancemythen?
-
"Sourcecode OOP, Executable kein OOP."
Damit hast du dich komplett disqualifiziert, Xin.
-
dv_ schrieb:
"Sourcecode OOP, Executable kein OOP."
Wie kommst Du jetzt darauf ? Wo steht denn das ?
-
Shade Of Mine schrieb:
Wo ist der Unterschied zwischen:
class Triangle { function draw() {} } class Circle { function draw() {} } function foo($s) { $s->draw(); }
und
struct Shape { void (*draw)(); }; struct Triangle { void (*draw)(); }; struct Circle { void (*draw)(); }; void foo(void* s) { ((Shape*)s)->draw(); }
und
function Triangle() { this.draw=function(){} } function Circle() { this.draw=function(){} } function foo(s) { s.draw(); }
JS und PHP haben für alle Objekte eine gemeinsame Basis: den Objekttyp. Am Objekttyp kann sich die Sprache orientieren, um die richtige Funktion zu rufen.
In C++ wird der Objekttyp erst in die Klasse eingefügt, wenn eine virtuelle Funktion existiert.Probiere folgendes aus:
class OOP { int Daten; virtual ~OOP() {}; }; class NonOOP { int Daten; ~NonOOP() {} } int main( void ) { printf( "OOP: %d - NonOOP: %d\n,", sizeof( OOP ), sizeof( NonOOP ) ); return 0; }
Du wirst sehen, dass die OOP Variante größer ist, obwohl beide nur 4 Byte Daten enthalten, das ist die Typ-Kennzeichnung für das Objekt, an dem sich Algorithmen orientieren.
Wenn Du Dein C++ Beispiel kompilierst, wirst Du weiterhin feststellen, dass Du ohne virtual feststellst, dass immer Shape::Draw aufgerufen wird. Darum ist der C++-Code nicht objektorientiert.
Ich rate dringend dazu, wenn Du virtual nutzt, also C++-Unterstützung nutzt, OOP-Klassen zu verwenden, denn ich garantiere nicht dafür, dass der Hack mit virtual funktioniert.
Shade Of Mine schrieb:
class Triangle { } class Circle { } show(Tirangle s) {} show(Circle s) {}
Der letzte Code ist Nice und show ist ne multimethod.
Ah... das mit der Multimethod habe ich eben nicht kapiert.
Um Multimethoden zu realisieren, muss das Objekt einen Objekttyp besitzen. "Plain Classes" kannst Du nicht unterscheiden, weil der Objekttyp fehlt.
Sobald Du Multimethoden nutzen möchtest, musst Du also den Objekttyp zwangsläufig haben und sobald Objekte den Objekttyp haben, besitzen sie eine gemeinsame Basis.
Das wird in Java ja durch die implizite Ableitung von "class Object" ausgedrückt.Shade Of Mine schrieb:
Auch der Template Code in C++ gehört da eigentlich dazu, aber du bist scheinbar noch nicht soweit zu erkennen dass man heutzutage alles zur Runtime machen kann.
Ich weiß grade nicht, welcher Code gemeint ist und die Freundlichkeit überhöre ich mal.
Shade Of Mine schrieb:
Ich habe mittlerweile echte Probleme zu verstehen was du unter OOP verstehst und was nicht. Anfangs dachte ich du meinst virtuelle Funktionen definieren OOP. Keiner meiner Codes hat virtuelle Funktionen beinhaltet. Dann dachte ich du meinst runtime polymorphie - aber alle meine Codes ermöglichen Runtime Polymorphie. Jetzt bin ich verwirrt.
Ich hoffe, ich konnte es etwas aufklären.
Shade Of Mine schrieb:
Ist es eigentlich möglich in JavaScript ein OO Programm zu schreiben? Was du als "memcpy" abtust - nämlich Object Cloning - ist etwa das pedant zur Vererbung in Java. Man kann vererbung ein bisschen simulieren wie in C - aber dann hat man JS nicht verstanden. Man hat einfach keine virtuellen Funktionen, Vererbung auch nicht.
Beides ist ja auch nicht benötigt. Und wenn man in C++ OOP betreibt, wie in C, hat man C++ auch nicht verstanden. Trotzdem ist es OOP.
Shade Of Mine schrieb:
Der Shape-Code ist OO JavaScript. Mehr OO wird nicht gehen. Selbst wenn Shape nicht abstrakt ist, sondern sagen wir eine final Funktion getId() hat, sieht der Code in JS nicht viel anders aus:
function Shape() { this.getId=function(){} } function Triangle() { this = new Shape(); this.draw = function(){} } function Circle() { this = new Shape(); this.draw = function(){} }
Es findet hier keine Vererbung statt, sondern Object Cloning. Und da es keine virtuellen Funktionen gibt, macht es auch keinen Sinn ein draw() in Shape reinzupacken.
Stimmt, Du musst in JS ja auch nicht angeben, welchen Typ Du einer Funktion übergibst.
Du Benennung als virtual in der Basisklasse ist notwendig, um das Interface statisch kompilierbar zu machen.
In JS ist überhaupt nichts statisch kompiliert.Shade Of Mine schrieb:
Oder Vererbung in PHP - das ist nichts anderes als Code Reuse - das Interface definiert das Objekt. zB wo man in Java ein Interface Showable mit der abstrakten funktion show() nehmen würde, würde ich in PHP einfach keine Vererbung verwenden.
Das interessante dabei ist:
class Triangle { function show(); } class Circle { function show(); } function foo($s) { $s->show(); }
ist ziemlich genau 1:1 die Umsetzung von folgendem Java Code:
interface Showable { abstract void show(); } class Triangle implements Showable { public void show(){} } class Circle implements Showable { public void show(){} }
Jetzt ist plötzlich einer dieser Codes OO und der andere nicht?
Beide sind OO und beide besitzen implizit die Objekttyp-Information, die in C++ nicht existieren würde, wenn man virtual wegläßt.
Warum benutzt Du in Java abstract, lehnst aber in C++ "virtual ...=0" ab?
Shade Of Mine schrieb:
PHP hat ein schwaches typ system - ich brauche interfaces nicht. Java hat ein starkes typsystem ich brauche die interfaces dort. C++ bietet beides: starkes typsystem über Showable und auch starkes (was sich aber manchmal wie schwaches anfühlt) über Templates.
Und genau da beisst sich deine Definition. Deine OOP Definition (die ich wirklich nicht mehr nachvollziehen kann) basiert auf Java. Ich würde soweit gehen und sagen dass sie auf Java ziemlich genau zutrifft. Aber allein PHP - und PHP hat nun wirklich keine kreativen Ideen wie man an die OOP rangehen kann - widerspricht deiner Definition.
Wo ist der Widerspruch? Wo beißt sich etwas, ich verstehe nicht, welchen Punkt Du mir als Widerspruch vorlegen willst!?
Shade Of Mine schrieb:
Also bitte, definiere OOP nochmaleimal ganz genau. Dann widerlegen wir dir das und wir können alle diesen Thread ruhen lassen. Es hat schon seinen Grund warum man nirgendwo eine vernünftige feste Definition von OOP liest - denn OOP ist eben eine Denkweise und die lässt sich schwer definieren.
Ich arbeite dran. Es ist nicht ganz so einfach, eine möglichst interpretationsfreie Definition zu liefern und zwischendurch muss ich auch mal andere Dinge erledigen als nur diesen Thread.
Es ist aber schön, dass ich mir die Mühe nur mache, um widerlegt zu werden. Die Chance, dass die Zusammenfassung so verständlich wird, dass sie überzeugt, steht nicht zur Diskussion?
-
Xin schrieb:
OOP kommt dann rein, wenn Lampe zum Beispiel nicht mit Dynamo kombiniert wird, sondern von Energiequelle.
Energiequelle könnte Dynamo sein oder Akku.
Energiequelle::GetVoltage() wäre eine virtuelle Funktion, die beim Dynamo von der Drehzahl abhängt und beim Akku von der Ladung der Zellen.Ersetzen wir Energiequelle durch ein Abstraktes Konzept dass nicht direkt im Sourcecode vorkommt und implementieren Dynamo und Akku. Und geben Lampe dann ein Objekt von Dynamo oder Akku je nachdem wie wir lustig sind.
Genau das machen _alle_ meine Shape Codes. Die Implementierung von Energiequelle unterscheidet sich - da unterschiedliche Sprachen mir unterschiedliche Tools anbieten diese Implementierung vorzunehmen - aber das Konzept von Akku und Dynamo die miteinander austauschbar sind ist das essentielle in den Codes.
Die Implementierung sollte Nebensache sein.
-
dv_ ignoriere ich mal.
merker schrieb:
dv_ schrieb:
"Sourcecode OOP, Executable kein OOP."
Wie kommst Du jetzt darauf ? Wo steht denn das ?
Wie komme ich darauf?
Der Programmierer verlangt OOP, also ist der Sourcecode so geschrieben, dass mit OOP arbeiten soll.Wenn es allerdings keine abgeleiteten Objekte gibt, ist OOP nicht notwendig, es verlangsamt den Funktionsaufruf.
Erkennt der Compiler das, ist es sinnvoll OOP aus dem Programm zu entfernen, um das Executable zu beschleunigen.
Der Code, den der Compiler dann als Executable schreibt, arbeitet dann nur noch mit statischen Funktionsaufrufen, also nicht mehr objektorientiert.Wo steht das?
Es ist die logische Konsequenz, wenn der Compiler OOP rausoptimiert, dass der OOP-Quelle zu einem Nicht-OOP-Ziel kompiliert wird.
-
merker schrieb:
dv_ schrieb:
"Sourcecode OOP, Executable kein OOP."
Wie kommst Du jetzt darauf ? Wo steht denn das ?
Xin schrieb:
Was ist, wenn der Compiler erkennt, dass es kein Tier gibt, dass die methode überschreibt und deshalb den vcall herausoptimiert? immernoch oop?
OOP vom Entwickler gewünscht, vom kleveren Compiler rausoptimiert.
Sourcecode OOP, Executable kein OOP.
-
Shade Of Mine schrieb:
Xin schrieb:
OOP kommt dann rein, wenn Lampe zum Beispiel nicht mit Dynamo kombiniert wird, sondern von Energiequelle.
Energiequelle könnte Dynamo sein oder Akku.
Energiequelle::GetVoltage() wäre eine virtuelle Funktion, die beim Dynamo von der Drehzahl abhängt und beim Akku von der Ladung der Zellen.Ersetzen wir Energiequelle durch ein Abstraktes Konzept dass nicht direkt im Sourcecode vorkommt und implementieren Dynamo und Akku. Und geben Lampe dann ein Objekt von Dynamo oder Akku je nachdem wie wir lustig sind.
Was ist ein "abstraktes Konzept, das nicht direkt im Sourcecode vorkommt"?
-
Xin schrieb:
dv_ ignoriere ich mal.
merker schrieb:
dv_ schrieb:
"Sourcecode OOP, Executable kein OOP."
Wie kommst Du jetzt darauf ? Wo steht denn das ?
Wie komme ich darauf?
Der Programmierer verlangt OOP, also ist der Sourcecode so geschrieben, dass mit OOP arbeiten soll.Wenn es allerdings keine abgeleiteten Objekte gibt, ist OOP nicht notwendig, es verlangsamt den Funktionsaufruf.
Erkennt der Compiler das, ist es sinnvoll OOP aus dem Programm zu entfernen, um das Executable zu beschleunigen.
Der Code, den der Compiler dann als Executable schreibt, arbeitet dann nur noch mit statischen Funktionsaufrufen, also nicht mehr objektorientiert.Wo steht das?
Es ist die logische Konsequenz, wenn der Compiler OOP rausoptimiert, dass der OOP-Quelle zu einem Nicht-OOP-Ziel kompiliert wird.Du glaubst allen ernstens, dass OOP nur aus dynamic dispatch besteht? Mann, du hast wirklich eiskalt alle Messlatten vergraben. Lass dir gesagt sein: OOP ist mehr als nur dynamic dispatch.
Aber ignorier mich ruhig weiter. Irgendwann wirst du einsehen was für Unsinn du redest. Hoffentlich bevor es dich deinen Job kostet.
-
rüdiger schrieb:
Hier mal ein Beispiel mit Common Lisp (CLOS)
Ich erweitere das Sammelsurium einfach mal aus Spaß an der Freude mit Perl:
use fields; package Tier; sub new { return fields::new(shift); } sub laut { print "dunno\n"; } package Hund; use base 'Tier'; sub laut { print "wuff wuff\n"; } package Katze; sub new { return fields::new(shift); } sub laut { print "miau miau\n"; } package main; eval("eval 'new '.<> or new Tier")->laut;
~$ perl bsp.pl Hund wuff wuff ~$ perl bsp.pl STH dunno ~$ perl bsp.pl Katze miau miau
-
dv_ schrieb:
Du glaubst allen ernstens, dass OOP nur aus dynamic dispatch besteht? Mann, du hast wirklich eiskalt alle Messlatten vergraben. Lass dir gesagt sein: OOP ist mehr als nur dynamic dispatch.
Ist das alles, was als Begründung kommt?
Wenn Du mir etwas mitteilen möchte, dann stelle nicht nur Behauptungen auf, sondern begründe sie.
-
Was ist das denn für eine Frage? Du zeigst mir nichts und ich soll sagen, was das ist?
Hab ich 'ne Kristallkugel? Ich weiß ja nicht, was der Code da macht.
Nur weil da Miau rauskommt, weiß ich doch nicht, ob der Entwickler per OOP gelöst hat oder nicht.das bedeuted, dass deine definition in 90% aller großprojekte nichtmehr sinnvoll zum einsatz kommen kann. tolle definition, ehrlich. so mathematisch korrekt...und nützlich.
-
otze schrieb:
Was ist das denn für eine Frage? Du zeigst mir nichts und ich soll sagen, was das ist?
Hab ich 'ne Kristallkugel? Ich weiß ja nicht, was der Code da macht.
Nur weil da Miau rauskommt, weiß ich doch nicht, ob der Entwickler per OOP gelöst hat oder nicht.das bedeuted, dass deine definition in 90% aller großprojekte nichtmehr sinnvoll zum einsatz kommen kann. tolle definition, ehrlich. so mathematisch korrekt...und nützlich.
Keine Definition kommt sinnvoll zum Einsatz, wenn Du nicht die Informationen hast um eine Antwort zu geben.
Wer ein Auto mietet und an die Tankstelle fährst, stellt oft fest, dass das Auto fährt, obwohl man nicht weiß, ob man Benzin oder Diesel tanken muss.
Trotzdem ist entweder ein Benzinmotor drin - oder ein Diesel.Wenn man die Motorhaube öffnet oder sich in der Dokumentation informiert, dann kann man das entscheiden.
Man kann natürlich auch sagen, dass die Definition Benzin oder Diesel nichts taugt und einfach Kraftstoff verlangen.
-
Xin schrieb:
Ist das alles, was als Begründung kommt?
Wenn Du mir etwas mitteilen möchte, dann stelle nicht nur Behauptungen auf, sondern begründe sie.Die Grundlage von OO ist die sinnvolle Zusammenführung von Daten und Funktionalität zu Objekten. Punkt aus ende. Aber du kommst mir Spezialisierungen daher und nennst das OOP. Das ist so, als ob man sagt, dass ein Ding nur dann ein Vehikel ist, wenn es ein Lenkrad hat und Porsche heisst.
-
dv_ schrieb:
Xin schrieb:
Ist das alles, was als Begründung kommt?
Wenn Du mir etwas mitteilen möchte, dann stelle nicht nur Behauptungen auf, sondern begründe sie.Die Grundlage von OO ist die sinnvolle Zusammenführung von Daten und Funktionalität zu Objekten. Punkt aus ende. Aber du kommst mir Spezialisierungen daher und nennst das OOP. Das ist so, als ob man sagt, dass ein Ding nur dann ein Vehikel ist, wenn es ein Lenkrad hat und Porsche heisst.
Falsch, ich verlange Räder.
Räder funktionieren mit einem Fahrer (int), mit Beifahrer ( Array ) und auch als Transporter (Klasse).
Der Fahrer (int) kann aber auch zu Fuß gehen, genauso wie die Beifahrer und auch eine Palette kann man notfalls tragen.Ansonsten sind Diskussion mit Personen, die "Punkt aus ende" formulieren kaum nutzbringend.
-
Du weisst aber schon, dass Vehikel nicht unbedingt Räder brauchen, oder? Wozu braucht ein Schiff räder? Ja, ein Schiff ist ein Vehikel.
Davon abgesehen ist dein Beispiel überhaupt total verkorkst. Du bist extrem C++-versteift. Lerne doch endlich, dass es andere Modelle gibt. Verschiedene Beispiele anderer Sprachen wurden dir gezeigt.
-
Xin schrieb:
Wo steht das?
Es ist die logische Konsequenz, wenn der Compiler OOP rausoptimiert, dass der OOP-Quelle zu einem Nicht-OOP-Ziel kompiliert wird.Besten Dank für die Antwort.
Könnte Alpträume verursachen, wenn die Executable nicht mehr dem Sourcecode entspricht.
Ist aber wohl ein anderes Thema.
-
Was haben wir hier eigentlich. Wir haben zwei Parteien: Die eine hat eine schwammige, unpräzise Definition von OOP, die andere eine harte, präzise. Was mich dabei aber wundert ist, dass in einem Forum mit den übelsten Pedanten, ANSI-Standard-Fetischisten und undefined-behaviour-Propheten eben die unexakte, schwammige Definition besser angenommen wird. Müssten diese nicht alle (den Matheloser Jester mal ausgenommen) den Weg der peinlichst genauen Definition gehen? Woher kommt das? Liegt es vielleicht letzten Endes doch daran, dass die präzise Definition einfach nur unbrauchbar ist, weil sie einfach zu speziell ist?
Mir kommt es so vor, als definiert jemand "Speiseeis" als "Mischung aus Wasser und Milch in festem Aggregatszustand mit Zucker und Zartbitterschokoladepartikeln mit definierter Größe", während der Pöbel das einfach nur als "na Eis halt" definiert. Bei der ersten Definition ist eindeutig, dass Stracciatella gemeint ist. Der Pöbel hingegen kann sich theoretisch die Zunge am Trockeneis einfrieren, aber sollte da nicht schon längst der "common sense" eingesetzt haben?
-
Xin schrieb:
Was ist ein "abstraktes Konzept, das nicht direkt im Sourcecode vorkommt"?
Shape in dem C++ Template Beispiel
-
Oder auch Policy-Based Design genannt
-
minhen schrieb:
rüdiger schrieb:
Hier mal ein Beispiel mit Common Lisp (CLOS)
Ich erweitere das Sammelsurium einfach mal aus Spaß an der Freude mit Perl:
iiiih ist ja grauenhaft :p Aber dennoch schön OOP (auch wenn einige es hier nicht glauben mögen...)