Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Konvertierung von BigEndian-Werten (https://www.delphipraxis.net/169483-konvertierung-von-bigendian-werten.html)

p80286 25. Jul 2012 14:25

AW: Konvertierung von BigEndian-Werten
 
Liste der Anhänge anzeigen (Anzahl: 3)
Hallo und vielen Dank nochmal auch an Mr OR!
Ich habe alle Anregungen (sofern ich sie verstanden habe) einmal verwurstet und versucht sie an Hand eines Benchmarks zu beurteilen.

Delphi-Quellcode:
function Big2Little32c(ina:tpa4):integer;
var
  dd : integer;
begin
  dd:= ina^[3]+
      (ina^[2] shl 8)+
      (ina^[1] shl 16)+
      (ina^[0] shl 24);
  result:=dd;
end;

function Big2Little32H(ina:tpa4):integer;
begin
  result:=0;
  result:= result or
           ina[3] or
          (ina[2] shl 8) or
          (ina[1] shl 16) or
          (ina[0] shl 24);
end;

function Big2Little32R(ina:tpa4):integer;
type
  tLittRec=record
         case integer of
         1 : (wert:integer);
         2 : (aa: array [0..3] of byte);
  end;
var
  my : tLittRec ;
begin
  my.wert:=0;
  my.aa[0]:=ina[3];
  my.aa[1]:=ina[2];
  my.aa[2]:=ina[1];
  my.aa[3]:=ina[0];
  result:=my.wert;
end;

function SwapInt32(Value: Integer): integer; register;
asm
  BSWAP EAX
end;
Big2Little32c/function Big2Little32H sind etwa gleich schnell (im Rahmen der Messgenauigkeit)
SwapInt32 ist etwas schneller(-10%)
Big2Little32R(ina:tpa4):integer;
Braucht ca. die dreifache Zeit.

Da ich nur ca 1000-3000 Werte lesen muß ist der Unterschied eigentlich irrelevant, aber in diesem Falle ist small beautiful and fast.

Ich werde SirThornberrys Anregung aufgreifen und da noch ein "LängenMäntelchen" um legen, dann hab ich was ich will.

Vielen Dank nochmal
K-H

Falls es jemanden interessiert, im Anhang das Programm und die erhaltenen Werte.

himitsu 25. Jul 2012 16:11

AW: Konvertierung von BigEndian-Werten
 
Wobei du in Big2Little32R unnötig viel umkopierst.
Und da du sowieso alle Bytes wieder überschreibst, muß es auch nicht initialisiert werden (wert=0)
Delphi-Quellcode:
function Big2Little32R(ina:tpa4):integer;
type
  tLittRec=record
         case integer of
         2 : (aa: array [0..3] of byte);
  end;
var
  my : tLittRec absolute Result;
begin
  my.aa[0]:=ina[3];
  my.aa[1]:=ina[2];
  my.aa[2]:=ina[1];
  my.aa[3]:=ina[0];
end;

function Big2Little32R(ina:tpa4):integer;
type
  tLittRec= array [0..3] of byte;
var
  my : tLittRec absolute Result;
begin
  my[0]:=ina[3];
  my[1]:=ina[2];
  my[2]:=ina[1];
  my[3]:=ina[0];
end;

function Big2Little32R(ina: tpa4): LongInt;
var
  res: tpa4 absolute Result;
begin
  res[0] := ina[3];
  res[1] := ina[2];
  res[2] := ina[1];
  res[3] := ina[0];
end;

function Big2Little32R(ina: tpa4): LongInt;
begin
  tpa4(Result)[0] := ina[3];
  tpa4(Result)[1] := ina[2];
  tpa4(Result)[2] := ina[1];
  tpa4(Result)[3] := ina[0];
end;
Wobei alle Vier im Prinzip auf's Selbe rauslaufen, also nach dem Kompilieren.

p80286 25. Jul 2012 16:40

AW: Konvertierung von BigEndian-Werten
 
Dumme Frage
Delphi-Quellcode:
type
  tLittRec=record
         case integer of
         2 : (aa: array [0..3] of byte);
  end;
Fehlt der Integer absichtlich?
(das absolute finde ich stark, oft eingesetzt aber nie so!)

Gruß
K-H

himitsu 25. Jul 2012 16:43

AW: Konvertierung von BigEndian-Werten
 
Du hattest das 1:Integer ja nur für
Delphi-Quellcode:
my.wert:=0;
benutzt.
Und da dieses nun weg war, wurde 1:Integer auch nicht mehr benötigt. :angle:

p80286 25. Jul 2012 16:53

AW: Konvertierung von BigEndian-Werten
 
Nee da war noch
Delphi-Quellcode:
result:=aa.wert;
aber egal, auf jeden Fall ein Beispiel, das es viele Wege gibt.

Gruß
K-H

himitsu 25. Jul 2012 17:20

AW: Konvertierung von BigEndian-Werten
 
:oops: ganz vergessen :lol:

Nicht nur viele Wege ... auch viele Ansichten

Alle meine 4 Funktionen machen ganz genau das Selbe, also wenn man es Speichertechnisch betrachtet.
Nur daß der Quellcode anders aussieht, auch wenn er, wie gesagt, genau das Selbe macht.

Amateurprofi 26. Jul 2012 00:43

AW: Konvertierung von BigEndian-Werten
 
Oder so.
Der Compiler wird sich die richtige Funktion selber suchen.

Delphi-Quellcode:
FUNCTION ChangeEndian(value:Word):Word; overload;
asm
   {$IFDEF CPUX64}
   mov  rax,rcx
   {$ENDIF}
   XCHG al,ah
end;

FUNCTION ChangeEndian(value:DWord):DWord; overload;
asm
   {$IFDEF CPUX64}
   mov  rax,rcx
   {$ENDIF}
   bswap eax
end;

FUNCTION ChangeEndian(const value:UInt64):UInt64; overload;
asm
   {$IFDEF CPUX64}
   mov  rax,rcx
   bswap rax
   {$ELSE}
   mov edx,[esp+8]
   mov eax,[esp+12]
   bswap eax
   bswap edx
   {$ENDIF}
end;

FUNCTION ChangeEndian(value:SmallInt):SmallInt; overload;
asm
   {$IFDEF CPUX64}
   mov  rax,rcx
   {$ENDIF}
   XCHG al,ah
end;

FUNCTION ChangeEndian(value:Integer):Integer; overload;
asm
   {$IFDEF CPUX64}
   mov  rax,rcx
   {$ENDIF}
   bswap eax
end;

FUNCTION ChangeEndian(const value:Int64):Int64; overload;
asm
   {$IFDEF CPUX64}
   mov  rax,rcx
   bswap rax
   {$ELSE}
   mov edx,[esp+8]
   mov eax,[esp+12]
   bswap eax
   bswap edx
   {$ENDIF}
end;

Furtbichler 26. Jul 2012 06:08

AW: Konvertierung von BigEndian-Werten
 
Funktioniert der Compilerswitch auch zur Laufzeit?

Bummi 26. Jul 2012 06:36

AW: Konvertierung von BigEndian-Werten
 
welche Anwendung wechselt zu Laufzeit zwischen 32 und 64 Bit-Anwendung?

Amateurprofi 26. Jul 2012 11:31

AW: Konvertierung von BigEndian-Werten
 
Zitat:

Zitat von Furtbichler (Beitrag 1175947)
Funktioniert der Compilerswitch auch zur Laufzeit?

Ja, selbstverständlich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:38 Uhr.
Seite 2 von 2     12   

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