![]() |
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:
Gibt es hier eine Möglichkeit das ganze zu beschleunigen?
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; Vielen Dank für Vorschläge! |
AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
Na wir wäre es mit:
Delphi-Quellcode:
Also den String nur einmal holen.
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; |
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. |
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:
lauten.
ltemp[i + 1]
|
AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
Zitat:
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; |
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: |
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] <> '0');
Delphi-Quellcode:
(wenn wirklich nur 1 und 0, weil 'b' oder '3' auch ungerade sind)
l_arr[i] := Ord(Odd(Ord(ltemp[i]))) // Ord('1') ist Ungerade, also True, und Ord(True) ist 1
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. |
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.
|
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);
|
AW: Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
Zitat:
![]() ![]() ![]() ![]() ![]() ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz