Frage: StringList ohne SysUtils/Classes Units möglich?

Für Fragen von Einsteigern und Programmieranfängern...
alfware17
Beiträge: 210
Registriert: Di 14. Dez 2010, 23:27

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von alfware17 »

theo hat geschrieben: Do 6. Apr 2023, 17:16
wp_xyz hat geschrieben: Do 6. Apr 2023, 16:32 Sorry wenn das jetzt etwas sarkastisch klingt: Du willst also eine Datei mit 5 Millionen Zeilen in deinem Programm bearbeiten und die ganze Datei im Speicher vorhalten (denn sonst würdest du keine StringList verwenden), und machst dir Sorgen, warum das Programm um 100 KB größer ist? Verstehe ich nicht...
Der TE hat ja selbst gesagt: "Es ist für mich ein echtes psychologisches Problem".
Ich glaube, hier geht es weniger um technische Fragen.
Falsches Forum? :wink:
Was bitte schön, hat denn die Größe der EXE mit der Menge der verarbeiteten Daten zu tun? Und ja natürlich kann das Programm trotzdem klein sein, wenn das zur Laufzeit dynamisch aufgebaut wird.

Das mit dem falschen Forum glaube ich beinahe an dieser Stelle auch. Wer hat das bzw baut das größte Programm? Sorry sollte sich nur dem Tonfall anpassen, lassen wir das. Es war durchaus eine zutiefst technische Frage.

Und ja ich brauche zur Laufzeit die ganze Datei im Speicher, weil das nun mal am schnellsten geht. Nachladen sind Dateioperationen und die brauche ich dann auch noch, wenn die Dateien zu groß für den RAM, für die Listen oder zu teuer für den Algorithmus werden, dann wird Teile-und-Herrsche gemacht.

alfware17
Beiträge: 210
Registriert: Di 14. Dez 2010, 23:27

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von alfware17 »

af0815 hat geschrieben: Do 6. Apr 2023, 14:46
alfware17 hat geschrieben: Do 6. Apr 2023, 13:34 Kann ich die Typdeklaration und die Methoden von TStringList eventuell sehen, im Quellcode meine ich? Wahrscheinlich ja, wenn der ganze Lazarus quelloffen ist und sich selbst compilieren kann. Aber wo suche ich?
Im Quelltext, wo du einer variablen den Typ TStringlist zuordnest. Dort einfach die rechte Maustaste betätigen und der erste Punkt oben sollte "Find declaration of TSTringList" sein. Damit findest du die deklaration. Damit wirst du aber nicht ganz glücklich sein, tiefer geht es , wenn du dann immer den Parent verwendest und somit tiefer in das Objekt einsteigst. Es geht aber auch das du gleich in das Loadxx einsteigst, ebenso mit rechter Maustaste die Deklaration laden. Also alles keine Hexerei.
Nunja, ich dachte eher an eine Unit so zum Anschauen, aber wenn es nicht anders geht als über die IDE. Und nein ich benutze die von Lazarus gar nicht, sondern die von FPC und da ist es nix mit rechte Maustaste. Aber ich kann es ja mal versuchen. Dachte nur, man kommt an den Code einfacher ran

PascalDragon
Beiträge: 954
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von PascalDragon »

alfware17 hat geschrieben: Do 6. Apr 2023, 21:20
MmVisual hat geschrieben: Do 6. Apr 2023, 13:55 Die DLL musst du schon selbst schreiben (mit Lazarus), die Funktionen von der TStringList rein packen und entsprechend als Interface bereit stellen.
Wie das genau geht, dazu gibt es einige Anleitungen im Netz.
EIn toller letzter Satz. Ich wollte mit einem kleinen Programm und einer kleinen DLL beginnen um zu sehen, was man da machen muß damit es auf Bedarf nachgeladen wird. Daher meine Bitte um ein Beispiel.
Dynamisches Nachladen von Klassen in Bibliotheken ist nicht möglich, da sowohl die Anwendung als auch die Bibliothek ihre eigene „Instanz” der RTL, wodurch Operationen wie is nicht über die Modulgrenzen hinweg funktionieren. Vom Speichermanagement mal ganz abgesehen. Das Ganze würde erst sinnvoll funktionieren, sobald FPC Dynamic Packages unterstützt.

Außerdem ändert das Auslagern von Code nichts an der Gesamtgröße deiner Binaries, es sei denn mehrere deiner Anwendungen würden die Bibliothek nutzen. Wenn du also diese Bedingung nicht hast, dann würde ich das einfach lassen, da es einfach eine unnötige Komplexität hinzufügt.
alfware17 hat geschrieben: Do 6. Apr 2023, 13:34 Kann ich die Typdeklaration und die Methoden von TStringList eventuell sehen, im Quellcode meine ich? Wahrscheinlich ja, wenn der ganze Lazarus quelloffen ist und sich selbst compilieren kann. Aber wo suche ich?
Wie andere bereits gesagt haben, nutze einfach die „Finde Deklaration”-Funktionalität von Lazarus (zum Beispiel mit Strg + Klick).
alfware17 hat geschrieben: Do 6. Apr 2023, 13:34Kann man eventuell auch die SysUtils im Quellcode sehen?
Gleicher Punkt wie oben: Strg + Klick auf die Unit.
alfware17 hat geschrieben: Do 6. Apr 2023, 13:34Ich meine ja nur, weil ich da auch noch so eine Baustelle mit dem TSearchRec habe, die in 32/64bit anders läuft - ja ich weiß, ich stelle mich manchmal an...
Was meinst du hier?
alfware17 hat geschrieben: Do 6. Apr 2023, 13:34Wenn ich die Units sehen und teilweise übernehmen könnte, würden die EXE doch automatisch kleiner oder? Irgendwie habe ich in Erinnerung, daß der Linker dann eh nur die Funktionen mitnimmt, die auch gebraucht werden, oder sehe ich das falsch. Irgendworan muß es doch liegen, daß ein einfaches Uses Classes die EXE fast verdoppelt in der Größe.
Beachte bitte, dass der Sinn der RTL es ist das Betriebssystem zu abstrahieren. Wenn du also den Code zum Beispiel von der Windows RTL übernimmst, dann kannst du deine Anwendung nicht einfach auf eine andere Plattform portieren.

Zumindest unter Windows ist Smart Linking standardmäßig aktiviert, allerdings enthalten sowohl die SysUtils als auch die Classes Unit Funktionalitäten, die bei der Initialisierung der Units benötigt werden und dadurch wird eben einiges von selbst mit eingebunden.
FPC Compiler Entwickler

alfware17
Beiträge: 210
Registriert: Di 14. Dez 2010, 23:27

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von alfware17 »

Danke für all eure Erklärungen und Tips - ich kann hier so viel lernen.

Das konkrete Problem habe ich wie gesagt nun organisatorisch gelöst:
- für 64bit compiliere ich einmal mit CLASSES und Stringlist und entsprechendem Algorithmus dazu und einmal eben ohne.
Die Steuerung erfolgt über ein {$DEFINE} und Windows bzw Linux erstellen mir eine zweite Binary, die ich umbenenne (die ohne Stringlist erhält einen neuen Namen).
Der Aufruf des Algorithmus kommt eh nur in bestimmten Fällen (Eingabe und Ausgabe über Files, maximale Größe bzw Zeilenzahl und abschalten kann der User das ganze auch noch) zum Tragen und das wird dann wenn vorhanden und möglich erkannt und es geht schneller. Kann aber auch abbrechen, und dann wird restarted und man hatte eben Zeitverlust, das nehme ich mal in Kauf.
- für 16/32bit ist das Ganze unsichtbar (wieder Compilerschalter) und zusätzlich ist auch die SysUtils nicht mit drin, eben wegen Größe.
Weil du fragst, was ich mit dem SearchRec meine, na das hier:

Code: Alles auswählen

PROCEDURE Loesche_Alle_Temp;
VAR anz: LONGINT;
    dir: {$IFDEF BIT_64} TSearchRec; {$ELSE} SearchRec; {$ENDIF}
BEGIN
   anz:=0;
   {$IFDEF BIT_64}
   IF FindFirst(tempbest+'.*',faAnyFile,dir)=0 THEN BEGIN
      REPEAT
         Loesche_Temp(dir.Name, anz);
      UNTIL FindNext(dir)<>0;
      FindClose(Dir);
   END;
   {$ELSE}
   FindFirst(tempbest+'.*',AnyFile,dir);
   WHILE (DosError=0) DO BEGIN
      Loesche_Temp(dir.Name, anz);
      FindNext(dir);
   END;
   {$IFNDEF DOS} FindClose(Dir); {$ENDIF}
   {$ENDIF}
   IF anz>0 THEN Log('F',1,'   '+StrCardInt(anz)+'x TMP');
END;
Lasse ich die Sonderbehandlung für 64bit weg, kann ich es nicht mehr compilieren weil irgendwie der SearchRec oder die Proceduren in der Bibliothek anders definiert sind, so ganz schlau werde ich nicht aus der Fehlermeldung des (Batch) FPC. Wenn ich andersherum bei 32bit auch TSearchRec nehme, handele ich mir die SysUtils und damit eine EXE-Vergrößerung ein, ohne zusätzlichen Nutzen (ich habe sonst aus den SysUtils nix benutzt in dem Programm).

Zum Smart-Link - wie erkenne ich das beim Batch-FPC? Habe auf Anhieb den Switch nicht gefunden?

Und ja, das mit der DLL ist mir zu aufwändig und zu schwer.

Und die Unit bzw StringList Definition werde ich mal suchen, aber hey - in FreePacal gibt es kein String+Click, aber gut ich nehme Lazarus. Wenn ich mir die TString und die TStringList so anschaue, habe ich sofort beschlossen, das bleibt da alles fein in der Unit und ich baue nix nach bzw lasse es so wie es ist. Immerhin funktioniert mein Sort besser als der dort aus der Unit, das war ja ursprünglich auch Sinn und Zweck der Übung bzw meines ganzen 5.Algorithmus gewesen.

ABER: Danke, daß ich so "gezwungen war" mein Batch-Programm auch mal als Projekt im Lazarus anzusehen und zu compilieren, sprich eine andere IDE zu nehmen. Die EXE wird je nach Debug-Info Einstellung 950 KByte oder wieder 372 KByte (10 mehr???) groß, ob es Laufzeitabweichungen gibt, kann ich noch nicht sagen, habe mir das nur mal so gesichert.

thosch
Beiträge: 328
Registriert: Mo 10. Jul 2017, 20:32

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von thosch »

Hallo Alfware17,

vielleicht hilft Dir eine Lösung aus Tycooonuserinterface weiter. Dort gibt es statt einer TStringlist das array of String. Die Methoden müsstest Du zwar dann neu schreiben. Aber dort wird mit SetLength der Speicherplatz für einen neuen String festgelegt, der String dann an Strings[length(Strings)-1] angefügt. Es gibt dort nur die Methode addString.

Guck dazu die Unit tuiDropBox an oder tuiSelectBox

Den Download dafür gibt es hier: viewtopic.php?f=1&t=14881

In den beiden Units gibt es das Klassenfeld "strings" als array of string. Die addString() Methode zeigt, wie ein gültiger String dort angehängt wird.

Das ist keine fertige eigene Stringliste, aber vielleicht ein gangbarer Weg für Dein Problem. Der Code ist GPL, darf also frei kopiert und weiter verwendet werden, auch Codeteile dürfen in anderen Projekten verwendet werden. Es ist keine dll erforderlich und der Code läuft nicht nur in go32v2 sondern auch in Linux und Windows und mit Linux framebuffer.

Benutzeravatar
KodeZwerg
Beiträge: 110
Registriert: Mo 6. Feb 2023, 11:04
OS, Lazarus, FPC: Win64, Lazarus 64 [trunk], FPC win64-win32 [stable]
CPU-Target: x86_64

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von KodeZwerg »

5 Millionen Zeilen in den Speicher laden und zwar unter 16, 32 und 64 bit als eine (TString)List(e)?
Ich möchte ja kein Spielverderber sein aber für mich sieht das schon alleine vom "Index" her als unmöglich aus.
Bei 16 Bit wäre bereits bei 64kb Index aus die Maus.
Bei 32 Bit hättest Du zumindest schonmal basis Zugriff auf 2GB und mit ein wenig Trickserei sind es 4GB.
Also bleibt für diese Datenmenge eigentlich eh nur noch 64 Bit übrig.
Von daher würde ich empfehlen diese "es muss alles auf einmal reingequetscht werden" Methode nochmals überdenken und auf Blöcke umsteigen.

Bestimmt habe ich aber etwas wichtiges überlesen und es war anders gemeint.
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

alfware17
Beiträge: 210
Registriert: Di 14. Dez 2010, 23:27

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von alfware17 »

KodeZwerg hat geschrieben: Mi 19. Apr 2023, 00:23 5 Millionen Zeilen in den Speicher laden und zwar unter 16, 32 und 64 bit als eine (TString)List(e)?
Ich möchte ja kein Spielverderber sein aber für mich sieht das schon alleine vom "Index" her als unmöglich aus.
Bei 16 Bit wäre bereits bei 64kb Index aus die Maus.
Bei 32 Bit hättest Du zumindest schonmal basis Zugriff auf 2GB und mit ein wenig Trickserei sind es 4GB.
Also bleibt für diese Datenmenge eigentlich eh nur noch 64 Bit übrig.
Von daher würde ich empfehlen diese "es muss alles auf einmal reingequetscht werden" Methode nochmals überdenken und auf Blöcke umsteigen.

Bestimmt habe ich aber etwas wichtiges überlesen und es war anders gemeint.
Die 5 (bzw 20 jetzt) Millionen Zeilen sind nur der Maximalwert im Algorithmus-5 Fall und für 64bit. Ich habe 4 andere Verfahren und natürlich die Grenzen bei 32bit und 16bit, dafür gibt es ja das Teile-Und-Herrsche-Verfahren. Ich wollte jedoch sehen, wie weit ich es mit einem Rutsch - alles im RAM weil es da nun mal am schnellsten geht - treiben kann. Meine (einfach) verkettete Liste ist übrigens ähnlich schnell wie die Stringlist, nur habe ich dafür insgesamt für alle 4 alten Verfahren viel mehr Code als jetzt mit der Stringlist und das war der Reiz für mich. Da ich das Readln/Writeln natürlich als Flaschenhals identifiziert habe und blockwrite auch keine Punkte bringt (zu umständlich für mein Problem und getestet auch nicht viel schneller). Aber das load und save der Stringlist war gut. Wie gesagt in dem Fall: alles in den RAM, verarbeiten und wieder zurück auf die Platte.

Warf
Beiträge: 2118
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von Warf »

Die Unit Classes sowie die Unit SysUtils machen halt viel mehr als nur Typen und Funktionen bereitstellen (generell eine Faustregel wenns um FPC geht, Units stellen nicht nur Code oder Daten bereit, Units können das Programmverhalten maßgeblich beinflussen, und grade viele der Standard Units machen das auch sehr gerne). Classes initialisiert Threading und Synchronization, und SysUtils initialisiert extrem viele andere sachen (z.B. exception handling oder Internationalization). Daher wird das Programm dann aber auch plötzlich so groß. Ohne diese beiden Units hast du halt einen Großen Teil der FPC Sprachfeatures nicht. Und natürlich ist wenn man nur die Hälfte an Funktionalität zur verfügung hat, das Endergebnis kleiner.

Wenn es dir wirklich so sehr auf die Dateigröße ankommt, dann ist die einzige Konsequenz, das featureset was du benutzt zu reduzieren. So solltest du z.B. generell auf die verwendung von klassen verzichten, weil die generell recht viel overhead hinzufügen. Exception genauso (die bekommst du bei Klassen sowieso dazu weil Konstruktoren immer exception handler registreiren). Die System Unit fügt auch einiges an Overhead hinzu, so ist z.B. das Dateimanagement mit Read/Write und den File datentypen recht aufwendig, es ist viel einfacher schlanker die System APIs direkt zu verwenden.
Im grunde ist das beste wenn du den FPC einfach nur als eine art assembler benutzt um die Pascal syntax zu haben, aber keine der Integrierten Bibliotheken, und keine Features die nach den 70ern eingeführt wurden benutzt.
Ganz wichtig, vertraue keiner Unit die du nicht selbst geschrieben hast.

Das "Problem" damit ist halt, das viele neue Sprachfeatures benötigen zusätzlichen overhead. Das ist alles kein Problem bei modernen Rechnern, die diese Leistung bereitstellen können. Es ist im Grunde ein Tradeoff zwischen vereinfachter Programmierung, oftmals im Austausch für etwas Leistung oder Speicherverbrauch. Auch die Tatsache das der FPC cross plattform code erzeugen kann sorgt dafür das die generierten Dateien weniger optimiert sind. Statt spezialisiert auf eine sache muss es jetzt überall laufen.
(Free)Pascal ist eine Lebende Sprache die kontinuierlich weiterentwickelt wird, und der FPC ist ein Aktives Projekt. Neue Entwicklungen werden mit bestimmten Kompromissen (wie Effizienz, Speicher oder anderen Limitationen) kommen.
Wenn du Programme wie vor 20 Jahren schreiben willst, dann ist vermutlich die beste Option, keine Moderne Sprache mit Modernen Tools zu benutzen, sondern einfach eine Sprache (und potentiell Compiler) von vor 20 Jahren rauspacken, oder eine Sprache benutzen die Explizit nicht weiter Entwickelt wird (so unterstützen die meisten C compiler bis heute noch ansi C aus 1983, für die für die 1999 viel zu neumodisch ist).

Benutzeravatar
KodeZwerg
Beiträge: 110
Registriert: Mo 6. Feb 2023, 11:04
OS, Lazarus, FPC: Win64, Lazarus 64 [trunk], FPC win64-win32 [stable]
CPU-Target: x86_64

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von KodeZwerg »

Um Warf's Idee weiterzuverfolgen, kannst Du ja spaßenshalber im ISO mode Dein Projekt verwirklichen.
Damit bist Du im Standard Pascal modus und hast dementsprechend wenig Komfort aber vermutlich auch weniger Balast.
Hier findest ein minimal Beispiel dazu. (Wiki)
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

alfware17
Beiträge: 210
Registriert: Di 14. Dez 2010, 23:27

Re: Frage: StringList ohne SysUtils/Classes Units möglich?

Beitrag von alfware17 »

Danke für eure Tips. Weiter zurück als Writeln und Readln aus der System bzw DOS Unit wollte ich eigentlich nicht gehen - außer ich bekäme sie schneller (denn sie sind durchaus ein Flaschenhals). Aber nein, ich bin kein EXE-Größen-Fanatiker, die 16bit (Turbo 7) und 32bit (FPC) sind mit 80 bzw. 120kB ja vergleichbar, nur halt habe ich im 32bit ganz andere Möglichkeiten und Dimensionen. Sage mal 80-90% meiner Anwendungen passieren mit 32bit.

Ich war nur so erstaunt (und erbost :-) daß ich mir bei 64bit durch die einfache TSearchRec und TStringlist so viel mehr "Ballast" einhandle. Aber gut, Objekte... Und ich fand bzw finde die Aufteilung: 32bit ohne OO, 64bit mit OO wenn es denn sein soll, gar nicht mal so schlecht

Antworten