AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi und 64-Bit Programme

Ein Thema von Harry Stahl · begonnen am 25. Mär 2022 · letzter Beitrag vom 30. Mär 2022
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.538 Beiträge
 
Delphi 11 Alexandria
 
#1

Delphi und 64-Bit Programme

  Alt 25. Mär 2022, 19:27
Bei einem aktuellen Thread zum importieren von großen XML-Dateien habe ich mich gewundert, dass das Lesen einer 1,6 GB großen Datei nicht möglich sein sollte (also zumindest unter 64 Bit).

Habe dann mal spaßeshalber unter Windows als 64-bit-Programm versucht eine ca. 2 GB csv-Textdatei in eine Stringlist zu laden (die "star2002-full.csv" Datei von dieser Quelle: https://sdm.lbl.gov/fastbit/data/samples.html) . Das scheitert aber schon alleine daran, dass Delphi einen Integerüberlauf in der Procedure TStrings.LoadFromstream meldet.

Tja und wenn man sieht, dass dort - und an vielen anderen Stellen in der System.classes Hilfsvariablen mit dem Typ Integer deklariert sind, wird schnell klar, das kann nicht funktionieren, wenn der Inhalt oder der Wert einer Variablen größer als 2GB ist.

In der System.classes (aber auch System.Generics.collections) sind in vielen Klassen Schleifenvariablen, Enumeratoren, Rückgabewerte oder Parameter als Integer definiert.

Letztlich funktionieren alle solche Klassen nicht, wenn ein Index > 2GB ist.

Ist das heutzutage noch zeitgemäß? Wo manche Rechner inzwischen 64 GB oder mehr Arbeitsspeicher haben? Müsste nicht zumindest für die 64-Bit-Plattform hier Int64 an allen diesen Stellen verwendet werden? Ich kann mir allerdings auch vorstellen, dass das dann ein ziemlicher (Um-) Bruch wäre und zu vielen Seiteneffekten bei bestehenden Programmen führen würde.

Was meint Ihr?

Geändert von Harry Stahl (25. Mär 2022 um 19:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#2

AW: Delphi und 64-Bit Programme

  Alt 25. Mär 2022, 19:58
Natürlich wäre es besser int64 einzusetzen und durch bedingte Compilierung auch halbwegs kompatibel zu halten. Aber auch bei < 64 bit ist es aus meiner Sicht fatal, Integer einzusetzen statt Cardinal. Das war nötig weil der Index bei Listenfunktionen durch Rückgabe von -1 als "Fehlercode" missbraucht wird. Durch diese allgemein verbreitete Unsitte wird ja auch bereits die Hälfte des Wertebereichs verschenkt.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Delphi und 64-Bit Programme

  Alt 26. Mär 2022, 07:38
Ein Int32 mit Vorzeichen geht im positiven Zahlenbereich bummelig bis 2 Milliarden.
Möglicherweise war man der Ansicht, dass eine StringList für derartige und noch größere Datenmengen schlicht der falsche Container ist. 64 Bit hin oder her.
Die Stream-Klassen beispielsweise kommen mit entsprechenden Größenordnungen zurecht.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Delphi und 64-Bit Programme

  Alt 26. Mär 2022, 08:23
Tja und wenn man sieht, dass dort - und an vielen anderen Stellen in der System.classes Hilfsvariablen mit dem Typ Integer deklariert sind, wird schnell klar, das kann nicht funktionieren, wenn der Inhalt oder der Wert einer Variablen größer als 2GB ist.
Das Problem ist dort, dass der Inhalt des Streams in einen einzigen String geladen wird. Und ein String hat eine feste Struktur, so dass man den Längenzähler nicht einfach auf 64-Bit erweitern kann.

Man kann in eine Stringliste aber prinzipiell auch problemlos mehr Daten laden, wenn man das Problem der Stringlänge beim Laden umgeht:
Delphi-Quellcode:
type
  TMyStringList = class(TStringList)
  private
    FNoClear: Boolean;
  public
    procedure Clear; override;
    procedure LoadFromStream(Stream: TStream; Encoding: TEncoding); override;
  end;

{ TMyStringList }

procedure TMyStringList.Clear;
begin
  if not FNoClear then
    inherited;
end;

procedure TMyStringList.LoadFromStream(Stream: TStream; Encoding: TEncoding);
var
  Size, LengthToLastLineBreak: Integer;
  Buffer: TBytes;
begin
  BeginUpdate;
  try
    FNoClear := True;
    while True do
    begin
      Size := Min(Stream.Size - Stream.Position, 1073741814);
      if Size = 0 then
        break;
      SetLength(Buffer, Size);
      Stream.Read(Buffer, 0, Size);
      Size := TEncoding.GetBufferEncoding(Buffer, Encoding, DefaultEncoding);
      SetEncoding(Encoding); // Keep Encoding in case the stream is saved
      LengthToLastLineBreak := Length(Buffer);
      while (LengthToLastLineBreak > 0) and (Buffer[LengthToLastLineBreak - 1] <> 10) do
        Dec(LengthToLastLineBreak);
      Stream.Seek(LengthToLastLineBreak - Length(Buffer), TSeekOrigin.soCurrent);
      SetTextStr(Encoding.GetString(Buffer, Size, LengthToLastLineBreak - Size));
    end;
  finally
    FNoClear := False;
    EndUpdate;
  end;
end;
Das ist jetzt nur schnell hingeschludert und funktioniert nicht für alle Zeilenumbrüche.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (26. Mär 2022 um 08:28 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.538 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Delphi und 64-Bit Programme

  Alt 26. Mär 2022, 13:00
Danke für Euer Feedback.

Es ging mir jetzt nicht speziell um dieses StringList-Demo. Wie man die zitierte 2GB großte Text-Datei (mit 17,5 Mio Zeilen) trotzdem in eine Stringlist laden kann, weiß ich (Daniel hat es schon angedeutet, mit Hilfe eines Streamreaders)).

Es ging mir um die generelle Frage, ob man die Klassen (z.B. mit Überladungen) auf 64-Bit Nutzung umstellen bzw. erweitern sollte. Könnte mir vorstellen, z.B. bei größeren Simulationen, wo z.B. 5 Mrd. Werte wegen der Echtzeit-Anforderung im Arbeitsspeicher gehalten müssen, es u.U. doch in irgendeinem Zusammenhang auch hilfreich sein könnte, ein TDictionary zu verwenden. Aber auch das könnte ich nicht verwenden, da dort in der Klasse z.B. "FCount" und alle anderen relevanten Zahlenwerte Integer sind.

Mir ist schon klar, dass ist hier eine Diskussion von untergeordneter Relevanz und nichts was jetzt in Delphi vorrangig behandelt werden müsste (wenn überhaupt).

Mich hat es nur interessiert, ob irgendjemand hier auch schon mal an ähnliche Grenzen in Umgang mit sehr großen Datenmengen in Zusammenhang mit 32/64 Bit Implementierung der Standard-Delphi Klassen gestoßen ist und irgendwo Erweiterungsbedarf gesehen hätte.

Geändert von Harry Stahl (26. Mär 2022 um 13:45 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Delphi und 64-Bit Programme

  Alt 26. Mär 2022, 14:09
Sicher wäre es wünschenswert, wenn es weniger Grenzen geben würde. Allerdings sollte man dabei auch nicht vergessen, dass die vorhandenen Klassen für so große Datenmengen, wie Daniel auch schon angedeutet hat, schlicht nicht ausgelegt sind.

Es wäre daher sinnvoller für diesen Zweck nicht die vorhandenen Klassen zu erweitern, sondern komplett neue zu entwickeln, die intelligenter mit solchen Datenmengen umgehen. Zum Beispiel wäre es sinnvoll, wenn man mit mehreren Threads arbeiten könnte, um so die Lade- und Zugriffszeiten zu verkleinern.

Dafür wären aber ganz andere Ansätze erforderlich als sie aktuell in Delphi implementiert sind. In anderen Systemen gibt es dafür ja auch schon einiges.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#7

AW: Delphi und 64-Bit Programme

  Alt 27. Mär 2022, 10:42
Da kann ich nur zustimmen. Schön wär's, wenn die alten Verfahren nur mit größeren Typen kompiliert werden müssten. Aber das ist nur ein Traum.

Dann also lieber neu, mit besseren Strategien. Es gibt (jenseits von XML) Datenformate, die extra für Streaming leicht verändert werden bzw. speziell für Streaming empfohlene Verfahren.

Hab mal zum Spaß 2GB XML in VS Code geöffnet. Ich hätte es ihm zugetraut, aber auch nach diversen Warnungen "starte mich neu mit 4GB Speicherreservierung" war da nichts zu machen. Was VS Code ganz nett macht, es schaltet mit einem Hinweis das Parsing bei großen Dateien ab, deswegen war ich auf die Idee gekommen, das einfach mal doof auszuprobieren. Anderswo wird also auch nur mit Wasser gekocht.
Gruß, Jo
  Mit Zitat antworten Zitat
HRolle

Registriert seit: 29. Dez 2021
Ort: Görlitz
44 Beiträge
 
Delphi 12 Athens
 
#8

AW: Delphi und 64-Bit Programme

  Alt 27. Mär 2022, 16:57
Für große Textdateien, natürlich auch für große XML-Dateien, würde ich Notepad++ (kann in der neuesten Version 8.3 mit Dateien > 2GB umgehen) oder PilotEdit (kann in der professionellen Variante bis zu 400GB große Dateien editieren) empfehlen. Beide Programme arbeiten offensichtlich mit Streaming, halten also nur eine bestimmte Teilmenge des Textes im Hauptspeicher.

Für große Datenfelder, wie gelegentlich bei Simulationsrechnungen notwendig, würde ich ebenfalls mit Streams oder einer Aufteilung eines Feldes von z.B. 5Mrd Double-Werten in mehrere Teilfelder arbeiten. Der Index im Stream ist bei Delphi die Position-Eigenschaft und die ist Int64.
Hannes
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Delphi und 64-Bit Programme

  Alt 27. Mär 2022, 19:44
Hallo,
hier widerspreche ich mal Daniel.

Einer der oft propagierten Vorteile von 64Bit ist ja gerade der Zugriff auf mehr als 2 (?), 4 GB Speicher.
Hier müsste Embarcadero auch bei StringList nacharbeiten.

Andere mit 64Bit erzeugten Programme können das ja auch.

Wobei man ja nicht weiß, wie viel RAM ein Anwender wirklich in seinem Rechner hat.
Oft wird ja Chunking benutzt, also das Aufteilen der Datei in einzelne Bereiche.
Unter 64Bit könnten größere Bereiche oder mehr Bereiche geladen werden, in Abhängigkeit des tatsächlichen Speichers.

Ich hatte mal unter 32Bit mit StringList's in einer StringList gearbeitet, dass klappte sogar ...
Heiko
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Delphi und 64-Bit Programme

  Alt 27. Mär 2022, 21:06
Gibt es nicht ganz genau dafür den Typ NativeInt?

Zitat:
NativeInt repräsentiert eine Untermenge der Integer-Zahlen. Der Bereich von NativeInt ist von der aktuellen Plattform abhängig. Auf 32-Bit-Plattformen entspricht NativeInt dem Typ Integer. Auf 64-Bit-Plattformen entspricht NativeInt dem Typ Int64.
Meine Schleifenvariablen, Array-Indizes usw. sind auch immer vom Typ NativeInt .

Ist ja in anderen Sprachen genauso (size_t in C++, isize/usize in Rust, ...).
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


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 20:12 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