Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Suboptimale Klassenoperatoren? (https://www.delphipraxis.net/184134-suboptimale-klassenoperatoren.html)

himitsu 1. Mär 2015 15:11

Delphi-Version: 2006

Suboptimale Klassenoperatoren?
 
Weiß eigentlich jemand, warum man einige Operatoren echt bescheuert implementiert hat?

Inc, Dec, Include und Exclude müssten ja eigentlich als Var-Parameter existieren und nicht mit einem nutzlosen Result-Parameter?
Im Ergebnis verliert man dadurch doch gerade den Vorteil dieser Funktionen Prozeduren, welche eigentlich direkt die Variable verändern und nicht erst eine Kopie erstellen und damit das Original überschreiben. :wall:




Das jetzt noch zu ändern wäre wohl zu spät. :?

Uwe Raabe 1. Mär 2015 16:47

AW: Suboptimale Klassenoperatoren?
 
Zitat:

Zitat von himitsu (Beitrag 1291920)
Inc, Dec, Include und Exclude müssten ja eigentlich als Var-Parameter existieren und nicht mit einem nutzlosen Result-Parameter?

Sorry, aber ich weiß im Moment nicht, was du meinst. Reden wir hier von Record-Operatoren?

Helmi 1. Mär 2015 17:05

AW: Suboptimale Klassenoperatoren?
 
Zitat:

Zitat von himitsu (Beitrag 1291920)
Inc, Dec, Include und Exclude müssten ja eigentlich als Var-Parameter existieren und nicht mit einem nutzlosen Result-Parameter?
Im Ergebnis verliert man dadurch doch gerade den Vorteil dieser Funktionen Prozeduren, welche eigentlich direkt die Variable verändern und nicht erst eine Kopie erstellen und damit das Original überschreiben. :wall:

Widersprichst du dir da nicht selbst?

wenn sie var-Parameter hätten, dann würde ja das Original überschrieben werden
als Function mit Rückgabewert bleibt ja das Original unberührt

Sir Rufo 1. Mär 2015 17:15

AW: Suboptimale Klassenoperatoren?
 
Wisst ihr (ausgenommen Uwe, der weiß es) eigentlich, was das mit dem
Delphi-Quellcode:
class operator
auf sich hat?

Delphi-Quellcode:
type
  TFoo = record
    Value: Integer;
    class operator Inc( a: TFoo ): TFoo;
  end;

{ TFoo }

class operator TFoo.Inc( a: TFoo ): TFoo;
begin
  Result.Value := a.Value + 1;
end;

procedure Test;
var
  LFoo : TFoo;
begin
  LFoo.Value := 1;
  Inc( LFoo );
end;
Preisfrage: Welchen Wert hat jetzt
Delphi-Quellcode:
LFoo.Value
?
  1. 1
  2. 2
Ich würde das mal ausprobieren und dann einfach nur wundern. Lösung: B

SMO 1. Mär 2015 17:27

AW: Suboptimale Klassenoperatoren?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1291930)
Wisst ihr (ausgenommen Uwe, der weiß es) eigentlich, was das mit dem
Delphi-Quellcode:
class operator
auf sich hat?

Ich weiß es auch. Und ich glaube, himitsu will darauf hinaus, dass es einfach unsinnig ist und der Compiler suboptimalen Code produziert.

Sei i: Integer, dann produziert "Inc(i)" Code, der den Inhalt von i an Ort und Stelle ("In-Place") erhöht.
In Rufos Beispiel produziert "Inc( LFoo )" dagegen Code, der TFoo.Inc(LFoo) aufruft, was eine temporäre Kopie von LFoo erstellt, die erhöht, nur um das Ergebnis dann gleich wieder LFoo zuzuweisen. Also praktisch: "LFooTemp := LFoo.Inc; LFoo := LFooTemp;" Dieser zusätzliche Schritt mit der Kopie erscheint unnötig und kann mit größeren Records Leistung verschwenden.

Sir Rufo 1. Mär 2015 17:35

AW: Suboptimale Klassenoperatoren?
 
Ja und? Ein Record kann ja nun auch etwas umfangreicher als ein
Delphi-Quellcode:
Integer
sein und auch das
Delphi-Quellcode:
Inc
kann dann durchaus etwas anspruchsvoller sein als einfach nur einen Wert hochzuzählen.

Und da man eben nicht weiß (und es eben komplexer sein kann) ist es genau so umgesetzt worden.

SMO 1. Mär 2015 17:44

AW: Suboptimale Klassenoperatoren?
 
Der springende Punkt ist, dass Inc und Dec für Standardtypen In-Place-Operationen sind und deshalb auch für Class Operators sein sollten.
Das wäre konsistenter und schneller. Wenn ich "komplexeres" Verhalten und eine Kopie möchte, kann ich auch einfach TFoo + 1 benutzen.
Wenn der Delphi-Compiler besser optimieren würde, dann wäre das kein Ding. Leider tut er es aber nicht...

himitsu 1. Mär 2015 17:50

AW: Suboptimale Klassenoperatoren?
 
Da die es nicht wussten, sollte es "normal" implementiert sein, also als VAR.

Wenn der Typ das nicht unterstützt, dann kann man es "intern" immernoch anders umsetzen.
Delphi-Quellcode:
class operator TMyRecord.Inc(var Value: TMyRecord);
var
  Temp: TMyRecord;
begin
  Temp := Value;
  ...
  Value := ...;
end;
Genau genommen fehlt sogar noch die Inc-Version mit zwei Parametern. :wall:
Delphi-Quellcode:
Inc(i, 123);


Zitat:

Zitat von Uwe Raabe (Beitrag 1291927)
Reden wir hier von Record-Operatoren?

Ja und Nein.

Aus technischen Gründen ist es "anfangs" nur für Records implementiert wurden.
Warum man vergessen hat das für Interfaces zu bauen, weiß ich nicht. (das ginge schon immer)
Dankt ARC wäre es, inzwischen seit XE4, auch möglich das bei Objekten (Klassen) zu benutzen. :zwinker:

Und grade bei Objekten wird der das immer mehr, wenn nun auch noch Objektinstanzen erstellt und freigegeben werden müssen, statt nur einem billigem Record.
Ein Vorteil bei den Objekten ist, daß man dort tricksen kann und bei diesen Operatoren einfach die selbe Objektreferenz zurückgibt. (wenn man blind hofft, daß Emba diese Funktionen nicht doch mal für zwei Objekte benutzt)

Sir Rufo 2. Mär 2015 07:13

AW: Suboptimale Klassenoperatoren?
 
So kann man sich täuschen.

Ich dachte immer, dass ein
Delphi-Quellcode:
var
  Value: Integer;

Inc( Value );
intern so funktioniert, dass der Wert von
Delphi-Quellcode:
Value
ausgelesen, dann um 1 erhöht (ergibt einen neuen Wert, der auch Speicher belegt) und dann zurückgeschrieben wird.
Delphi-Quellcode:
procedure Inc( var AValue : Integer );
begin
  AValue := AValue + 1;
end;
oder noch etwas anders geschrieben
Delphi-Quellcode:
function IntegerInc( AValue : Integer ): Integer;
begin
  Result := AValue + 1;
end;

procedure Inc( var AValue : Integer );
begin
  AValue := IntegerInc( AValue );
end;
Also ganz genau wie das hier bei den Records passiert, da ein Record eben auch nur einen komplexerer Wert darstellt.

Stevie 2. Mär 2015 07:59

AW: Suboptimale Klassenoperatoren?
 
Das Ding ist, dass der Compiler bei nem Integer schlau genug ist, auch einfach nen inc daraus zu generieren ohne temporäre Resultvariable. Das ist bei operator overloading leider nicht der Fall - Stichwort Return value optimization (beziehungsweise das Fehlen eben dieser).


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz