Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres? (https://www.delphipraxis.net/211420-array-integer-setzen-mit-strtointdef-gibt-es-schnelleres.html)

juergen 13. Sep 2022 18:28

Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Hallo,

ich lese aus einer Tabelle bestimmte Felder in ein ClientDataSet.
Damit bin ich schon mal recht schnell.

Es gibt nun ein Tabellen-Feld als String (dxMemData1.Fields[8]), welches *immer exakt* 4320 Zeichen enthält (Nullen oder Einsen, aber eben als String).

Nun muss ich bestimmte Berechnungen damit anstellen. Dazu ist es zwingend notwendig diesen String in ein Array of Integer zu packen.
Mein Profiling hat mir schon geholfen diverse andere Optimierungen vorzunehmen, aber das Füllen des Array of Integer dauert noch viel zu lange, weil das so oft aufgerufen wird. Da habe ich keine Idee wie ich das beschleunigen könnte. Hier mein Codeschnipsel:

Delphi-Quellcode:
VAR
l_arr: ARRAY [0 .. 4319] OF Integer;
BEGIN
  FOR i := 0 TO 4319 DO
  BEGIN
    l_arr[i] := StrToIntDef( frm_Test_Framework.dxMemData1.Fields[8].AsString[i + 1], 9 );
  END;
...
END;
Gibt es hier eine Möglichkeit das ganze zu beschleunigen?

Vielen Dank für Vorschläge!

Fritzew 13. Sep 2022 18:40

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Na wir wäre es mit:

Delphi-Quellcode:
procedure strToArray;
VAR
  i: Integer;
  l_arr: ARRAY [0 .. 4319] OF Integer;
  ltemp : String;
BEGIN
  ltemp :=  frm_Test_Framework.dxMemData1.Fields[8].AsString;
  if length(ltemp) <> 4320 then exit;

  FOR i := 0 TO 4319 DO
  BEGIN
    if ltemp[i] = '0' then
    l_arr[i] := 0 else
    if ltemp[i] = '1' then
    l_arr[i] := 1 else
    l_arr[i] := 9;
  END;

END;
Also den String nur einmal holen.

dummzeuch 13. Sep 2022 19:02

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Wenn es immer nur 0 oder 1 sind, kann man Fritzew's if/then/else durch

Delphi-Quellcode:
l_arr[i] := Ord(ltemp[i]) - Ord('0');


ersetzen. Evtl. Ord('0') noch durch eine Konstante ($30) ersetzen.

Und was ich erst vor kurzem gelernt habe: Eine While-Schleife, die vom Maximum auf 0 zählt ist schneller als eine For-Schleife von 0 bis Maximum. (Ich muss zugeben, dass mich das erschreckt hat, ich dachte, das optimiert der Compiler selbst.)

Und wenn auch das noch zu langsam ist, kann man statt mit Array+Index auch mit Pointern arbeiten. Das wird dann zwar schlechter lesbar aber vermulich nochmal deutlich schneller.

juergen 13. Sep 2022 19:04

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
@Fritzew,
Vielen Dank!!
Ursprünglich waren es ca. 51 Sekunden, jetzt sind es ca. 31 ms!!

Ein Hinweis noch.
Der String beginnt im Standard bei 1. Es muss also
Delphi-Quellcode:
ltemp[i + 1]
lauten.

Fritzew 13. Sep 2022 19:10

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Zitat:

Ein Hinweis noch.
Der String beginnt im Standard bei 1. Es muss also ltemp[i + 1] lauten.
Ja das habe ich übersehen war nur so hingedaddelt

Aber wenn du sicher bist das nur 0 und 1 vorkommen dann ist mit Sicherheit der Ansatz von Dummzeuch besser also

Delphi-Quellcode:
i := 4320;

While I > 0 do begin
  l_arr[i-1] := Ord(ltemp[i]) - $30);
  dec(i);
 end;

juergen 13. Sep 2022 19:10

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
@dummzeuch,

auch dir vielen Dank!!
Deine Version ist ca. 29 ms schnell.
Diese beiden Varianten sind für meinen Test-Case völlig ausreichend.

Das Thema ist für mich erledigt. Allen noch einen schönen Abend! :dp:

himitsu 13. Sep 2022 19:16

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Jupp, natürlich ist es immer sinnvoll Zwischenergebnisse zwischenzuspeichern, wenn sie dann mehrmals zigtausende Male wiederverwendet werden.

Zitat:

Delphi-Quellcode:
l_arr[i] := Ord(ltemp[i]) - Ord('0');

ginge auch Binär, anstatt mathematisch
Delphi-Quellcode:
l_arr[i] := Ord(ltemp[i] <> '0');

Delphi-Quellcode:
l_arr[i] := Ord(Odd(Ord(ltemp[i]))) // Ord('1') ist Ungerade, also True, und Ord(True) ist 1
(wenn wirklich nur 1 und 0, weil 'b' oder '3' auch ungerade sind)
Und es gäbe auch fertige Funktionen, um diesen Binär-String in eine Bit-Sequenz (Bit-/ByteArray) zu konvertieren, ähnlich dem HexToBin bzw. Office.Hex2Bin



Warum Array of Integer?
OK, vom Zugriff her am Schnellsten, aber auch 32 Mal mehr Speicher, als Inhalt.

Uwe Raabe 13. Sep 2022 20:44

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Da jeder Char ja zwei Byte groß ist, könnte man den String ab Stelle 1 mit einem simplen Move in ein ARRAY [0 .. 4319] OF Word kopieren und dort jedes Word mit AND $0001 auf die entsprechende Zahl bringen. Klappt aber halt nur, wenn es nicht wirklich Integer sein muss.

KodeZwerg 13. Sep 2022 22:18

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Ich habe keine Ahnung ob schneller... aber zumindest noch eine relativ simple Konvertierungsmöglichkeit ->
Delphi-Quellcode:
DeinByteArray := TEncoding.UTF8.GetBytes(DeinString);

himitsu 14. Sep 2022 09:39

AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
 
Zitat:

Zitat von KodeZwerg (Beitrag 1511777)
aber zumindest noch eine relativ simple Konvertierungsmöglichkeit ->
Delphi-Quellcode:
DeinByteArray := TEncoding.UTF8.GetBytes(DeinString);

Dafür müsstest du hier aber auch noch eine passende Codepage basteln, welche '0' nach #0 und '1' nach #1 übersetzt. (UTF-8 wäre falsch)

https://stackoverflow.com/questions/...-under-windows
http://www.barrcentral.com/help/beps...age_Editor.htm
https://softwareengineering.stackexc...-file-encoding
https://www.quora.com/How-do-I-create-my-own-encoding
https://libexpat.github.io/doc/writi...stom-encoding/
...


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:03 Uhr.
Seite 1 von 2  1 2      

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