Properties - Vor- und Nachteile
-
anton_zeiler = Troll
bitte nicht füttern.
-
@theta: danke, aber bitte passt nicht? Dass das mit dem Assembler sarkastisch ist weiß ich selbst. Der Rest ist meine Meinung zu OO und wenn es hier nicht gewollt ist, dass ich diese teile auch gut. Zumal ich finde dass diese Meinung gar nicht falsch ist.
Super Forum, war zwar nur kurz hier, aber was solls...
-
StephanSch schrieb:
GPC schrieb:
Ja, weil sie Logik implementieren könnnen. Sehe ich kein Problem. Man muss ja keine 3000 Zeilen Property schreiben.
Dazu schreibt die MSDN:
"Use a method when the operation is expensive enough that you want to communicate to the user that they should consider caching the result."Genau so halte ich es auch.
GPC schrieb:
Erstens kann sich auch ein Feld ändern.. wir leben in einer Multithreading-Welt. Und zweitens klingt der zweite Satz schon etwas merkwürdig. Es gibt genug Beispiele, in der Properties sich ändernde Werte zurückgeben.. und ich sehe da kein Problem.
Die MSDN sieht da aber offensichtlich schon ein Problem. Auch dort heißt es zu dem Thema.
"Use a method when calling the member twice in succession produces different results."Da ist die MSDN nicht den HTML-Code wert, mit dem sie erstellt wurde
Es gibt so zig viele Properties, die Werte zurückliefern, die sich ändern können. Nicht nur in den Windows Forms, auch in zig Bibliotheken. Mag sein dass das von den MS-Leuten mal als Designidee gedacht war.. aber durchgesetzt hat es sich nicht. Und ich sehe auch nicht warum es problematisch sein sollte.
GPC schrieb:
Ansonsten gibt's bei mir nur Properties und Methoden in der öffentlichen Schnittstelle. Ich hatte deswegen auch noch keine Performanceeinbrüche.
Ich wie gesagt schon und das sogar gravierend.
Und das kam GANZ SICHER von Properties? Ich verwende sie praktisch ausschließlich und meine Programme haben nie Probleme. Die IL-Anweisungen beim Zugriff auf eine Property sind auch.. na ja.. übersichtlich ^^ Es ist mehr als bei einem Feld, klar, weil es im Endeffekt ein virtual call sein kann. Aber das darf die Performance nicht ins unerträgliche reißen.
Ich werde mich in Zukunft wohl exakt an die Vorgabe halten:
"Use a property when the member is a logical data member."Die Vorgabe: "Keine Felder in der Schnittstelle" sollte mehr gelten
Ansonsten würd ich deinen Code nicht unbedingt pflegen wollen.
Properties sind eine feine Sache, aber bei ihrem Einsatz kann man auch mal schnell den Überblick verlieren und alles mögliche "reinstopfen" und "raushauen".
Na ja, so knifflig sind sie jetzt auch nicht. Es gibt sicher schwierigere Entscheidungen als Properties oder nicht
-
GPC schrieb:
GPC schrieb:
Ansonsten gibt's bei mir nur Properties und Methoden in der öffentlichen Schnittstelle. Ich hatte deswegen auch noch keine Performanceeinbrüche.
Ich wie gesagt schon und das sogar gravierend.
Und das kam GANZ SICHER von Properties? Ich verwende sie praktisch ausschließlich und meine Programme haben nie Probleme. Die IL-Anweisungen beim Zugriff auf eine Property sind auch.. na ja.. übersichtlich ^^ Es ist mehr als bei einem Feld, klar, weil es im Endeffekt ein virtual call sein kann. Aber das darf die Performance nicht ins unerträgliche reißen.
Sein Problem ist die Range Check Elimination, die bei seinem Code mit Properties nicht greift. Siehe dazu die Diskussion auf mycsharp.de. Nur scheint er das nicht wahrhaben zu wollen und verteufelt Properties jetzt im allgemeinen...
-
Zwergli schrieb:
Sein Problem ist die Range Check Elimination, die bei seinem Code mit Properties nicht greift. Siehe dazu die Diskussion auf mycsharp.de. Nur scheint er das nicht wahrhaben zu wollen und verteufelt Properties jetzt im allgemeinen...
Danke für den Link
Fail druid, I salute to you.
-
StephanSch schrieb:
Dravere schrieb:
Die einzige Kritik, welche man bringen könnte, ist, dass die gleiche Syntax für den Zugriff auf Properties wie auf Felder verwendet wird und daher Verwirrung stiften kann.
Die MSDN rät zumindest bei Arrays strikt von der Nutzung von Properties ab und das zur Recht!
Wenn man bedenkt das im Code kaum ein Unterschied zu einem gewöhnlichen Arrayzugriff zu sehen ist, ist das mehr als nur verwirrend.
Das mag bei einer 0815 Applikation nicht der Fall sein, aber bei komplexen umfangreichen Code durchaus.
Das wäre auch bei einer 0815 Applikation, was auch immer du darunter verstehst, verwirrend. Code liest sich genau gleich, egal was für eine Applikation man programmiert ... lol
Die MSDN rät aber nicht deswegen davon ab, wenn du die MSDN mal korrekt liest. Problem ist, dass man von aussen Zugriff auf die Innereien des Objektes bekommt. Das widerspricht dem Ansatz von OO.
Zudem ist mir ein Rätsel, was genau du hier als verwirrend siehst. Nur weil man ein Indexer auf ein Objekt anwenden kann, ist dies doch nicht verwirrend?
StephanSch schrieb:
Ich habe schon etliche Properties gesehen, die dutzende Zeilen Code enthielten.
Nur weil es ein paar Zeilen Code enthält, muss dies noch nicht schlimm sein. Zum Beispiel können ein paar Validierungen durchgeführt werden. Oder wenn ein
IEnumerable
zurückgegeben wird, kann auch eine Linq-Expression dort stehen. Sowas sehe ich durchaus als legitim an in einem Property.Zudem wer duzende Zeilen Code in einer Methode hat, hat sowieso meistens ein Design-Problem.
Und schlussendlich: Nur weil ein Feature missbraucht werden kann, heisst dies sowieso nicht, dass man es nicht einführen soll. Sonst dürfte man gar keine Programmiersprache entwickelnStephanSch schrieb:
Dravere schrieb:
Und nicht zuletzt: Ist vielleicht .Net die falsche Grundlage für Performance kritische Anwendungen?
Das .NET per se nicht geeignet ist für zeitkritische Anforderungen ist ein Mythos, genau wie bei Java.
Man kann durchaus von einer .NET Applikation erwarten das sie auch die erforderliche Performance bringt.
Dies als Mythos zu bezeichnen, kommt meistens von den Java Leuten oder Leuten, welche nicht verstanden haben, was andere genau sagen wollten. Du kannst gar keine zeitkritischen Anforderungen mit Java oder C# realisieren, weil dir jederzeit der GC, JIT oder sonst was einen Strich durch die Rechnung machen können. Du hast einfach zu wenig Kontrolle über die Rahmenbedingunen der Ausführung. Zudem kann ein Kompiler nachwievor viel aggressiver optimieren bei C oder C++ Code.
Ein Mythos dagegen ist, dass man keine performante Anwendungen in C# oder Java realisieren kann. Man kann auch C# oder Java Code so optimieren, dass auch grössere Aufgaben meistens in vernünftiger Zeit erledigt werden. Wenn es aber eben darum geht, das letzte Bisschen zu optimieren, also zeitkritische Applikationen zu entwickeln, dann hat man mit C# oder Java keine Chance gegen C oder C++.
Zwergli schrieb:
Sein Problem ist die Range Check Elimination, die bei seinem Code mit Properties nicht greift. Siehe dazu die Diskussion auf mycsharp.de. Nur scheint er das nicht wahrhaben zu wollen und verteufelt Properties jetzt im allgemeinen...
...
Dann soll er halt auf Properties verzichten. Wird ihn halt nur jeder auslachen bei der ArgumentationGrüssli
-
anton_zeiler schrieb:
OO hat mit Objekten zu tun, klar.
Das hast du verblüffend schnell erkannt.
anton_zeiler schrieb:
Somit haben Properties in C# wohl etwas mit OO zu tun.
Das ist falsch! Properties sind ein Werkzeug zur Realisierung der OOP, sie sind aber nicht notwendig, um eine OO-Sprache zu realisieren. Sie sind ein weiteres Sprachkonstrukt, genau wie die foreach-Schleife.
Willst du mir nun weismachen, man bräuchte foreach Kontrollstrukturen um Programme schreiben zu können?
anton_zeiler schrieb:
Felder sollte nie öffentlich gemacht. Und falls du doch meinst dann schau dir Assembler an.
Deine Aussagen sind ziemlich irrelevant, weil hier niemand behauptet hat, man solle Felder öffentlich zugänglich machen.
-
Dravere schrieb:
Dies als Mythos zu bezeichnen, kommt meistens von den Java Leuten oder Leuten, welche nicht verstanden haben, was andere genau sagen wollten. Du kannst gar keine zeitkritischen Anforderungen mit Java oder C# realisieren, weil dir jederzeit der GC, JIT oder sonst was einen Strich durch die Rechnung machen können. Du hast einfach zu wenig Kontrolle über die Rahmenbedingunen der Ausführung. Zudem kann ein Kompiler nachwievor viel aggressiver optimieren bei C oder C++ Code.
Darum geht es überhaupt nicht. Niemand hat ausgesagt, dass eine interpretierte Sprache keinen Overhead mit sich bringt und plattformspezifische Otimierungen, z.B. durch Inline-Assembler und prozessorabhängige Opcodes mit C# zu realisieren sind.
Es ging um die Aussage, ob Java oder .NET überhaupt die notwendige Performance leisten können oder prinzipiell ungeeignet sind für jegliche Performance-Anwendungen.
Und pauschal zu sagen, nimm kein .NET, wenn du Performance willst, ist nunmal völliger Unsinn. Es hängt ganz davon ab, was überhaupt realisiert werden soll und wie konkret die Anforderungen aussehen.
In Echtzeitsystemen habe ich auch konkrete Anforderungen an die Rechtzeitigkeit, die mir ein Standard-Betriebssystem nicht gewährleisten kann. Da nutzt mir C/C++ auch nicht weiter, weil ich ohne Treiber auch den Kernel mit dem Scheduler und Filesystem dazwischen geschaltet habe.
Dravere schrieb:
Ein Mythos dagegen ist, dass man keine performante Anwendungen in C# oder Java realisieren kann. Man kann auch C# oder Java Code so optimieren, dass auch grössere Aufgaben meistens in vernünftiger Zeit erledigt werden.
So ist es!
Dravere schrieb:
Wenn es aber eben darum geht, das letzte Bisschen zu optimieren, also zeitkritische Applikationen zu entwickeln, dann hat man mit C# oder Java keine Chance gegen C oder C++.
Das ist zweifelsohne korrekt.
Dravere schrieb:
Dann soll er halt auf Properties verzichten. Wird ihn halt nur jeder auslachen bei der Argumentation
Welche Argumentation? Und wer hat gesagt, ich wolle auf Properties verzichten?
-
GPC schrieb:
Die Vorgabe: "Keine Felder in der Schnittstelle" sollte mehr gelten
In C# kann eine Schnittstelle ohnehin keine Felder enthalten.
-
StephanSch schrieb:
Es ging um die Aussage, ob Java oder .NET überhaupt die notwendige Performance leisten können oder prinzipiell ungeeignet sind für jegliche Performance-Anwendungen.
Und pauschal zu sagen, nimm kein .NET, wenn du Performance willst, ist nunmal völliger Unsinn. Es hängt ganz davon ab, was überhaupt realisiert werden soll und wie konkret die Anforderungen aussehen.
Das habe ich aber so nie gesagt. Ich habe nur die Frage in den Raum gestellt, ob vielleicht .Net für Performance kritische Anwendungen die falsche Wahl ist. Diese Frage sollte man sich durchaus stellen. Ich habe nie irgendetwas in der Richtung behauptet, dass .net prinzipiell ungeeignet sei für jegliche Performance-Anwendungen.
StephanSch schrieb:
Welche Argumentation? Und wer hat gesagt, ich wolle auf Properties verzichten?
Naja, wenn du alle diese Nachteile bei den Properties siehst und dann noch daran glaubst, dass sie für diesen Performance-Einbruch verantworlich sind, wirst du in der Zukunft sicherlich des Oefteren aus Properties verzichten. Nur solltest du dabei nie auf die Argumentation im mycsharp Forum verweisen oder eine ähnliche bringen
Grüssli
-
dravere_mobile schrieb:
Naja, wenn du alle diese Nachteile bei den Properties siehst und dann noch daran glaubst, dass sie für diesen Performance-Einbruch verantworlich sind, wirst du in der Zukunft sicherlich des Oefteren aus Properties verzichten.
Ich betrachte überall Vor- und Nachteile und höre mir auch Kritiken an. Die genannten Nachteile stammen immerhin von einer Person, die auf dem amerikanischen Markt einen Bestseller zur CLR geschrieben hat.
Diese Person rät genausowenig, wie ich von Properties ab, sondern geht detailliert auf diese ein.
Zum Thema Performance. Natürlich sind die Properties kritisch für die Performance, wenn sie nicht geinlined werden. Es sind immer noch Methoden.
Wenn ich ILDASM zu Rate ziehe, sehe ich sofort das der Compiler selbst im Release-Build unter aktivierter Optimierung einen callvirt IL-Befehl vom Typ instance float64[] ::getArray() ausführt.
callvirt wird vom JIT-Compiler derart übersetzt das die CLR auch eine NullReferenceException auslösen kann. Die Überprüfung auf null wird auch bei nicht virtuellen Instanzmethoden durchgeführt und ist langsamer als ein normaler call.
-
StephanSch schrieb:
Das ist falsch! Properties sind ein Werkzeug zur Realisierung der OOP, sie sind aber nicht notwendig, um eine OO-Sprache zu realisieren.
Du gehst hier von der üblich engstirnigen OOP-Definition aus, die einer Liste von Features entspricht. Fast nichts ist für OOP notwendig, nicht einmal Klassen. Darum kannst du auch in C objektorientiert programmieren. Nur fehlen dir da ein paar Werkzeuge, die das ganze etwas angenehmer machen.
StephanSch schrieb:
Sie sind ein weiteres Sprachkonstrukt, genau wie die foreach-Schleife.
Willst du mir nun weismachen, man bräuchte foreach Kontrollstrukturen um Programme schreiben zu können?
Das ist ja mal eine mutige Schlussfolgerung
-
@StephanSch: hast du auch den geJITeten Code mal angeschaut und nicht nur den IL-Code vom C#-Compiler? Nur mit diesem lassen sich wirkliche Aussagen treffen ob der Code zur Laufzeit nun optimiert wurde oder nicht.
Der IL-Code ist zwar für vieles ein Indiz, aber nicht mehr.
-
StephanSch schrieb:
Die genannten Nachteile stammen immerhin von einer Person, die auf dem amerikanischen Markt einen Bestseller zur CLR geschrieben hat.
Good old Jeff ist normal schon eine Größe was .NET angeht... aber die meisten Punkte habe ich meiner Meinung nach schlüssig widerlegt und die anderen laufen auf: "OMG, Properties können Logik enthalten!!!" hinaus.
Zum Thema Performance. Natürlich sind die Properties kritisch für die Performance, wenn sie nicht geinlined werden. Es sind immer noch Methoden.
Sie sind ein Performancefaktor, den man in den allermeisten Fällen vernachlässigen kann. Der JIT-Compiler kann übrigens auch virtuelle Funktionen inlinen, wenn er feststellt, dass immer die gleiche aufgerufen wird. Unabhängig davon hängt dein ganz konkretes Performanceproblem nicht mit Properties zusammen.
-
GPC schrieb:
StephanSch schrieb:
Die genannten Nachteile stammen immerhin von einer Person, die auf dem amerikanischen Markt einen Bestseller zur CLR geschrieben hat.
Good old Jeff ist normal schon eine Größe was .NET angeht... aber die meisten Punkte habe ich meiner Meinung nach schlüssig widerlegt und die anderen laufen auf: "OMG, Properties können Logik enthalten!!!" hinaus.
Abgesehen davon:
Wow! Die Person hat einen Bestseller geschrieben! Dann muss es ein super Experte sein! Siehe auch in C++, da ist Jürgen Wolf der beste Mann was C++ betrifft. Er hat schliesslich den Bestseller C++ von A bis Z geschrieben!Ein Experte zeichnet sich nicht dadurch aus, dass er viele Bücher verkauft...
Zudem muss ein Experte nicht immer recht haben.Grüssli
PS: Ich will nichts gegen Jeffrey Richter sagen, nur gegen die Argumentation von StephanSch
-
Dravere schrieb:
gegen die Argumentation von StephanSch
Gegen welche Argumentation?
-
GPC schrieb:
Sie sind ein Performancefaktor, den man in den allermeisten Fällen vernachlässigen kann. Der JIT-Compiler kann übrigens auch virtuelle Funktionen inlinen, wenn er feststellt, dass immer die gleiche aufgerufen wird. Unabhängig davon hängt dein ganz konkretes Performanceproblem nicht mit Properties zusammen.
Die meisten Fälle sind nunmal nicht alle Fälle und kann inlinen ist auch nicht wird inlinen.
Woran soll der Performanceunterschied sonst liegen? Wenn der Unterschied in der IL nur beim callvirt liegt? Erzähl es mir, ich bin neugierig!
-
StephanSch schrieb:
GPC schrieb:
Sie sind ein Performancefaktor, den man in den allermeisten Fällen vernachlässigen kann. Der JIT-Compiler kann übrigens auch virtuelle Funktionen inlinen, wenn er feststellt, dass immer die gleiche aufgerufen wird. Unabhängig davon hängt dein ganz konkretes Performanceproblem nicht mit Properties zusammen.
Die meisten Fälle sind nunmal nicht alle Fälle und kann inlinen ist auch nicht wird inlinen.
Woran soll der Performanceunterschied sonst liegen? Wenn der Unterschied in der IL nur beim callvirt liegt? Erzähl es mir, ich bin neugierig!
Also du machst Performance-Aussage am IL-Code? Im anderen Board haben sie doch schon gesagt, dass du den geJittend Code (nativen Code) anschausen solltest, wobei ich selbst nicht weiß wie. Ähnlich Fall mit der JVM, jeder invokestatic kann/wird geinlined.
-
StephanSch schrieb:
GPC schrieb:
Sie sind ein Performancefaktor, den man in den allermeisten Fällen vernachlässigen kann. Der JIT-Compiler kann übrigens auch virtuelle Funktionen inlinen, wenn er feststellt, dass immer die gleiche aufgerufen wird. Unabhängig davon hängt dein ganz konkretes Performanceproblem nicht mit Properties zusammen.
Die meisten Fälle sind nunmal nicht alle Fälle und kann inlinen ist auch nicht wird inlinen.
Wenn ein Property als:
public class Foo { public IrgendeinTyp Bar { get; set; //Oder auch private set; } };
definiert ist, dann wird beim Zugriff auf Bar auch inlining durchgeführt. Nur bei virtuellen Properties kann es nicht immer gemacht werden.
Woran soll der Performanceunterschied sonst liegen? Wenn der Unterschied in der IL nur beim callvirt liegt? Erzähl es mir, ich bin neugierig!
Bezugnehmend auf den in myCSharp.de erstellten Thread liegt es an - wie dort schon festgestellt wurde - Range Check Elimination, die der Compiler nicht mehr durchführen kann. Du hast in dem Thread schon eine gewisse Beratungsresistenz gezeigt, obwohl dir ein Moderator dort deutlich erklärt, wo das Problem liegt und wie es zu lösen ist.
Das Problem mit deinem Code liegt bei der Klasse "TestTime2" nicht daran, dass die Property getLength so lahm wäre (lol, ich muss darüber immer noch lachen), sondern dass der JIT-Compiler kein RCE durchführen kann, da du nicht per array.Length auf die Längenangabe zurückgreifst sondern die Längenangabe UNABHÄNGIG vom Array holst.
Ich habe dir das mal umgeschrieben und dabei das Array erstmal geholt und dieses sowie dessen Länge dann in der Schleife benutzt. Im Prinzip ist die einzig wichtige Zeile: for (int i = 0; i < array2.Length; i++)class TestTime1 { public TestTime1() { } public double[] arr = new double[10000000]; } class TestTime2 { public TestTime2() { } public double[] Array { get { return arr; } } public int getLength { get { return arr.Length; } } private double[] arr = new double[10000000]; } class Program { static void Main(string[] args) { try { Stopwatch watch1 = new Stopwatch(); TestTime1 time1 = new TestTime1(); var array1 = time1.arr; watch1.Start(); for (int i = 0; i < array1.Length; i++) { array1[i] = i; i = (int)array1[i]; } watch1.Stop(); Stopwatch watch2 = new Stopwatch(); TestTime2 time2 = new TestTime2(); var array2 = time2.Array; watch2.Start(); for (int i = 0; i < array2.Length; i++) { array2[i] = i; i = (int)array2[i]; } watch2.Stop(); Console.WriteLine("Time for 1={0} and 2={1}", watch1.ElapsedMilliseconds, watch2.ElapsedMilliseconds); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
Edit: Und bevor du jetzt wieder mit "Aber du verwendest keine Properties" kommst, schau doch mal nach, wie die System.Array-Klasse die Eigenschaft "Length" definiert.. du wirst staunen, denn es ist ein Property!
-
Zeus schrieb:
Also du machst Performance-Aussage am IL-Code?
Sowohl am IL-Code, als auch an den gemessenen Zeiten, ja.
Zeus schrieb:
Im anderen Board haben sie doch schon gesagt, dass du den geJittend Code (nativen Code) anschausen solltest, wobei ich selbst nicht weiß wie. Ähnlich Fall mit der JVM, jeder invokestatic kann/wird geinlined.
Visual Studio hat dafür einen Disassembler und ich habe mir natürlich auch den JIT-Code angesehen.
i = (int)time2.Array[i]; 0000016a mov ecx,dword ptr [ebp-44h] 0000016d cmp dword ptr [ecx],ecx 0000016f call dword ptr ds:[005D26D0h] 00000175 mov dword ptr [ebp-6Ch],eax 00000178 mov eax,dword ptr [ebp-2Ch] 0000017b mov edx,dword ptr [ebp-6Ch] 0000017e cmp eax,dword ptr [edx+4] 00000181 jb 00000188 00000183 call 6E6775C0 00000188 movsd xmm0,mmword ptr [edx+eax*8+8] 0000018e cvttsd2si eax,xmm0 00000192 mov dword ptr [ebp-2Ch],eax
und
i = (int)array[i]; 0000016a mov eax,dword ptr [ebp-2Ch] 0000016d mov edx,dword ptr [ebp-50h] 00000170 cmp eax,dword ptr [edx+4] 00000173 jb 0000017A 00000175 call 6E5075C0 0000017a movsd xmm0,mmword ptr [edx+eax*8+8] 00000180 cvttsd2si eax,xmm0 00000184 mov dword ptr [ebp-2Ch],eax