AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Array of Integer setzen mit StrToIntDef(): gibt es was schnelleres?
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von juergen · begonnen am 13. Sep 2022 · letzter Beitrag vom 14. Sep 2022
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.175 Beiträge
 
Delphi 11 Alexandria
 
#1

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

  Alt 13. Sep 2022, 19:28
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!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#2

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

  Alt 13. Sep 2022, 19:40
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] = '0then
    l_arr[i] := 0 else
    if ltemp[i] = '1then
    l_arr[i] := 1 else
    l_arr[i] := 9;
  END;

END;
Also den String nur einmal holen.
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.623 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

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

  Alt 13. Sep 2022, 20:02
Wenn es immer nur 0 oder 1 sind, kann man Fritzew's if/then/else durch

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.
Thomas Mueller
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.175 Beiträge
 
Delphi 11 Alexandria
 
#4

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

  Alt 13. Sep 2022, 20:04
@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 ltemp[i + 1] lauten.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#5

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

  Alt 13. Sep 2022, 20:10
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;
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.175 Beiträge
 
Delphi 11 Alexandria
 
#6

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

  Alt 13. Sep 2022, 20:10
@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!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

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

  Alt 13. Sep 2022, 20:16
Jupp, natürlich ist es immer sinnvoll Zwischenergebnisse zwischenzuspeichern, wenn sie dann mehrmals zigtausende Male wiederverwendet werden.

Zitat:
l_arr[i] := Ord(ltemp[i]) - Ord('0');
ginge auch Binär, anstatt mathematisch
l_arr[i] := Ord(ltemp[i] <> '0');
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.
$2B or not $2B

Geändert von himitsu (13. Sep 2022 um 20:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 13. Sep 2022, 21:44
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#9

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

  Alt 13. Sep 2022, 23:18
Ich habe keine Ahnung ob schneller... aber zumindest noch eine relativ simple Konvertierungsmöglichkeit ->
DeinByteArray := TEncoding.UTF8.GetBytes(DeinString);
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

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

  Alt 14. Sep 2022, 10:39
aber zumindest noch eine relativ simple Konvertierungsmöglichkeit ->
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/
...
$2B or not $2B

Geändert von himitsu (14. Sep 2022 um 11:13 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:19 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