Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Operationen mit Bitstrukturen optimieren (https://www.delphipraxis.net/194224-operationen-mit-bitstrukturen-optimieren.html)

to-wer 30. Okt 2017 16:41

Operationen mit Bitstrukturen optimieren
 
Hallo zusammen,

habe ein Programm geschrieben, welche aus einem Datenstrom einen anderen erzeugt, was auch läuft. Allerdings braucht es bei 60.000 zu konvertierenden Bytes ca. 30 Sekunden, was an meiner vielleicht umständlichen Programmierung liegt. Nun möchte ich es gerne etwas schneller machen.
Es gibt immer drei Bytes auszuwerten, in denen bestimmte Bit positive oder negative Schrittweiten darstellen.

Bit No, 7 6 5 4 3 2 1 0
Byte 1 y+1 y-1 y+9 y-9 x-9 x+9 x-1 x+1
Byte 2 y+3 y-3 y+27 y-27 x-27 x+27 x-3 x+3
Byte 3 ev1 ev2 y+81 y-81 x-81 x+81 set set

Momentan habe ich die drei Hex-Bytes mit HexToBins in Strings gewandelt.
Die Schrittweiten berechne ich mit
dx:= StrToInt(hs1[8])-StrToInt(hs1[7])+9*StrToInt(hs1[6])-9*StrToInt(hs1[5])+3*StrToInt(hs2[8])-3*StrToInt(hs2[7])+27*StrToInt(hs2[6])-27*StrToInt(hs2[5])+81*StrToInt(hs3[6])-81*StrToInt(hs3[5]);

dy:= StrToInt(hs1[1])-StrToInt(hs1[2])+9*StrToInt(hs1[3])-9*StrToInt(hs1[4])+3*StrToInt(hs2[1])-3*StrToInt(hs2[2])+27*StrToInt(hs2[3])-27*StrToInt(hs2[4])+81*StrToInt(hs3[3])-81*StrToInt(hs3[4]);

Nutze das Bit also als Multiplikator in einem Term aus den verschiedenen Summanden.
Letztendlich habe ich auch schon die Formel jeweils durch feste Zuweisungen ersetzt, um zu sehen, wo der Flaschenhals ist. Viel hat es nicht gebracht - unter 10%.
Hat jemand eventuell eine Idee? Wenn nicht, ist auch nicht so schlimm. Dann wartet man eben.

Vielen Dank
Torsten

Neutral General 30. Okt 2017 16:57

AW: Operationen mit Bitstrukturen optimieren
 
Hallo,

Du solltest dir mal Bitoperationen anschauen. Das ganze Umwandeln in Strings und dann die Strings wieder in Ints umwandeln dauert Jahre.

Probier das mal:
Delphi-Quellcode:
function BytesToPoint(pt: TPoint; b1,b2,b3: Byte): TPoint;

const B1ValuesX: Array[0..7] of Integer = (1, -1, 9, -9, 0, 0, 0, 0);
const B1ValuesY: Array[0..7] of Integer = (0, 0, 0, 0, -9, 9, -1, 1);
const B2ValuesX: Array[0..7] of Integer = (3, -3, 27, -27, 0, 0, 0, 0);
const B2ValuesY: Array[0..7] of Integer = (0, 0, 0, 0, -27, 27, -3, 3);
const B3ValuesX: Array[0..7] of Integer = (0, 0, 81, -81, 0, 0, 0, 0);
const B3ValuesY: Array[0..7] of Integer = (0, 0, 0, 0, -81, 81, 0, 0);

var i: Integer;
begin
  for i:=0 to 7 do
  begin
    if (b1 and (1 shl i)) <> 0 then
    begin
      pt.X := pt.X + B1ValuesX[i];
      pt.Y := pt.Y + B1ValuesY[i];
    end;

    if (b2 and (1 shl i)) <> 0 then
    begin
      pt.X := pt.X + B2ValuesX[i];
      pt.Y := pt.Y + B2ValuesY[i];
    end;

    if (b3 and (1 shl i)) <> 0 then
    begin
      pt.X := pt.X + B3ValuesX[i];
      pt.Y := pt.Y + B3ValuesY[i];
    end;
  end;

  Result := pt;
end;
Je nach Geschmack gehts mit weniger Arrays und mehr Code oder vllt. generell mehr Code weil die Arrays von den Werten ja eigentlich ein vielfaches von 3 sind und man das auch so berechnen könnte, WENN das 3 Byte da nicht so aus der Reihe fallen würde.

Amateurprofi 30. Okt 2017 17:50

AW: Operationen mit Bitstrukturen optimieren
 
Eventuell so:
(Nicht getestet!)
Delphi-Quellcode:
PROCEDURE GetSteps(H1,H2,H3:Byte; var DX,DY:Integer);
begin
   DX:=Ord(H1 and 1>0) -      // dx:=StrToInt(hs1[8]) -
       Ord(H1 and 2>0) +      //     StrToInt(hs1[7]) +
       9*Ord(H1 and 4>0) -    //     9*StrToInt(hs1[6]) -
       9*Ord(H1 and 8>0) +    //     9*StrToInt(hs1[5])+
       3*Ord(H2 and 1>0) -    //     3*StrToInt(hs2[8]) -
       3*Ord(H2 and 2>0) +    //     3*StrToInt(hs2[7]) +
       27*Ord(H2 and 4>0) -   //     27*StrToInt(hs2[6]) -
       27*Ord(H2 and 8>0) +   //     27*StrToInt(hs2[5]) +
       81*Ord(H3 and 4>0) -   //     81*StrToInt(hs3[6]) -
       81*Ord(H3 and 8>0);   //     81*StrToInt(hs3[5]);

   DY:=Ord(H1 and 128>0) -    // dy:=StrToInt(hs1[1]) -
       Ord(H1 and 64>0) +     //     StrToInt(hs1[2]) +
       9*Ord(H1 and 32>0) -   //     9*StrToInt(hs1[3]) -
       9*Ord(H1 and 16>0) +   //     9*StrToInt(hs1[4]) +
       3*Ord(H2 and 128>0) -  //     3*StrToInt(hs2[1]) -
       3*Ord(H2 and 64>0) +   //     3*StrToInt(hs2[2]) +
       27*Ord(H2 and 32>0) -  //     27*StrToInt(hs2[3]) -
       27*Ord(H2 and 16>0) +  //     27*StrToInt(hs2[4]) +
       81*Ord(H3 and 32>0) -  //     81*StrToInt(hs3[3]) -
       81*Ord(H3 and 16>0);  //     81*StrToInt(hs3[4]);
end;

to-wer 30. Okt 2017 18:20

AW: Operationen mit Bitstrukturen optimieren
 
Hallo General,

erstmal vielen Dank für diese super strukturierte Funktion.
Habe sie integriert und den Zeitvergleich gemacht... die ganze Prozedur ist in Summe fast genauso langsam wie meine Variante. 2-3 Sekunden schneller.
Muss aber dazu sagen, dass ich gleichzeitig beim Berechnen noch die Zeichnung grafisch ausgebe und berechnete Strings in eine Listbox ausgebe.

Gerade habe ich getestet und festgestellt, dass die zwei Listbox.Items.Add Befehle pro Schleifendurchlauf die meiste Zeit brauchen.
Komplett mit Listbox und Zeichnen: 25 sek
ohne Listbox, mit Zeichnen: 8 sek
nur berechnen: 5 sek

Wenn ich hier die 2-3 Sekunden abziehe, ist die Funktion mindestens doppelt so schnell, fällt im gesamten Kontext aber nicht auf.

to-wer 30. Okt 2017 18:35

AW: Operationen mit Bitstrukturen optimieren
 
habe gerade herausgefunden, dass durch das Ausblenden der Listbox während der Ausgabe noch 10 Sekunden gespart werden können.
Das sollte vorerst reichen. Danke für eure Vorschläge und viele Grüße.

Torsten

Zacherl 30. Okt 2017 18:39

AW: Operationen mit Bitstrukturen optimieren
 
Delphi-Quellcode:
BeginUpdate
und
Delphi-Quellcode:
EndUpdate
Methoden der ListBox rufst du auf? Das wäre die korrekte Alternative zum kompletten Ausblenden der Komponente.

DeddyH 30. Okt 2017 18:58

AW: Operationen mit Bitstrukturen optimieren
 
Sind das nicht Methoden von TStrings, also hier von TListbox.Items?

Redeemer 30. Okt 2017 19:41

AW: Operationen mit Bitstrukturen optimieren
 
Sollte man den String nicht als string erstellen und später TStrings.Text setzen?

Zacherl 30. Okt 2017 19:51

AW: Operationen mit Bitstrukturen optimieren
 
Zitat:

Zitat von Redeemer (Beitrag 1384616)
Sollte man den String nicht als string erstellen und später TStrings.Text setzen?

Das kann man auch machen. Mit BeginUpdate/EndUpdate sollte die Performance theoretisch aber gleich gut sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:36 Uhr.

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