"codepage aware ANSIStrings"

Forum für alles rund um die MSEide und MSEgui
Antworten
mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

"codepage aware ANSIStrings"

Beitrag von mschnell »

Da fpc für das nächste offizielle Release die Delphi XE kompatiblen "codepage aware ANSIStrings" vorbereitet, und ich weiß, dass Du einen eigenen Compiler vorbereitest und Du in einer anderen Diskussion eine Aversion gegen "codepage aware Strings" dokumentiert hat, möchte ich hiermit festhalten, dass ich "codepage aware Strings" für ausgesprochen sinnvoll und nicht ernsthaft Performance-kritisch ansehe, wenn sie ordentlich (d.h. also besser als in Delphi XE gemacht und als momentan in fpc geplant) implementiert werden:

- Es sollte - wie in DXE und kompatibel damit - bei der Deklaration einer String-Variable möglich sein, sie auf eine Codierung festzulegen.
- mögliche (feste) Codierung:
. - Default (Implementierungs-spezifisch z.B. in DXE: fest UTF-16. Neu: in den Projekt-Optionen festgelegt)
. - ANSI (8 Bit) mit aktueller System-locale
. - ANSI mit jeweils festgelegter Locale
. - UTF 8
. - UTF 16
. - UTF 32
. - uncodiert 8 Bit (DXE: "Raw Byte String": Kennung $FFFF)
. - uncodiert 16 Bit (Raw Word String)
. - uncodiert 32 Bit (Raw DWord String)
. - uncodiert 64 Bit (Raw QWord String)
- Dazu sollte es einen "voll variabel codierten" Stringtyp geben, der bei einer Zuordnung immer den Typ des Senders übernimmt
- es sollte für den User möglich sein, eigene Stringcodierungen zu definieren (und dem Projekt die passenden Library-Funktionen - wie Umcodierungen und Vergleiche - zur Verfügung zu stellen)
- Zu jedem dieser String-Typen muss es auch den passenden "Character" geben.
- es wird automatisch umcodiert, wenn das nötig ist. Die Überprüfung muss im Compiler vorgesehen sein und braucht fast keine Rechenzeit, wenn nicht tatsächlich umcodiert wird)
. - ist der Ziel-Typ "voll dynamisch" wird nicht umcodiert
. - ist der Quell-Typ "voll dynamisch" wird natürlich nur umcodiert wenn der Ziel-Typ nicht schon passt. Die Überprüfung muss im Compiler vorgesehen sein und braucht fast keine Rechenzeit)
. - eine Zuordnung von irgendwie codierten Strings auf "Raw" Strings ergibt eine Exception.
- Sytemfunktionen verwenden in ihrer API immer den voll dynamischen String Typ (das kostet fast keine Rechenzeit, sofern nicht tatsächlich umcodiert werden muss, aber intern muss natürlich eine ganze Menge Software vorgehalten oder neu konzipiert werden: TStringlist muss z.B. mit unterschiedlichen Element-Größen arbeiten, was aber zum Speicher und Lesen nur eine zusätzliche Multiplikation zur Berechnung der Länge in Byte erfordert und pro String auch den Codierungstyp festhalten). z.B:
. - TStrings und alle Nachfolger (wie TStringList, TMemo, ...)
. - die GUI

Als nicht gelöst empfinde ich die folgenden (Unicode-) Probleme:
- Vergleich auf Gleichheit:
. - wie steuert der User, ob Case-sensitiv oder nicht ?
. - wie geht Case-insensitive in Unicode ?
. - wie geht man mit uneindeutigen Codierung (z.B. Unicode Code-Paaren) um ?
- zusätzlich bei Vergleich auf größer und kleiner: locale abhängige Sortierung ?!?!?!
- Enumerierung der Zeichen in einem String (manchmal hätte man gerne die Nummer (Adresse) des Code-Wortes, mal die des Codepoints, mal die Nummer des "sichtbaren Zeichens" - alles bis auf Wortnummer ist Perfomance-kritisch) :
. - Was bekommt man bei "Pos" heraus ?
. - Wie interpretieren copy() und delete() die Zahlen ?
. - was ist MyString[i] (vielleicht am besten überhaupt verboten !! )
. - sollte man standardmäßig einen Enumerator für Schleifen über die Zeichen eines Strings definieren (Syntax = ?!?!?!?) ?


Übrigens:
Zusätzlich zu der in fpc (svn-Version) meiner Ansicht nach (noch ? ) nicht ordentlichen Implementierung für (Unicode-) Strings sehe ich noch erheblichen weiteren Handlungsbedarf um Object-Pascal Zukunfts-kompatibel zu machen. Schau Dir beispielsweise die "parallel loop" und "future" Implementierung in Remobjects "Prism" an. Damit kann man eine Multicoce Architektur sinnvoll verwenden, ohne explizit Threads zu programmieren. Sowas kann man auch ohne .NET Framework in der Library realisieren !

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: "codepage aware ANSIStrings"

Beitrag von mse »

Meiner Meinung nach gehört Unicode Verarbeitung nicht in den Sprachumfang sondern in spezialisierte Bibliotheken, nach Möglichkeit Betriebssystemroutinen um die Umfangreichen Tabellen nicht für jeden Prozess einzeln vorhalten zu müssen.
Ich finde die FPC 2.6 Lösung Ideal, ein utf-16 string für reinen Text der für praktisch alle Anwendungen die Zeichen-Extraktion mittels Index zulässt und ein 8-Bit string der in der Regel Text in der Systemcodierung enthält, aber auch binäre Daten oder beliebige 8-bit-Codierungen enthalten kann, mit automatischer Umwandlung zwischen Systemcodierung <> utf-16. Wobei man über letzteres bereits diskutieren kann. Ich bin noch nicht sicher, ob das im MSEcompiler implementiert wird.
Ein "code page aware AnsiString" ist überflüssig, es macht wirklich keinen Sinn dafür die Sprache zu komplizieren und die Performance für alle Programme zu verschlechtern. Wer in einem Programm verschiedene 8-Bit Codierungen verwendet macht sich sowieso ein massgeschneidertes System um beste Performance zu erreichen.
Automatische Parallelverarbeitung/Multicore: Ich glaube das darf nicht überschätzt werden. Alle predigen man solle Parallelverarbeitung implementieren, die dann meist notwendigen Synchronisationsmechanismen darf man aber nicht verwenden, da dadurch alle Kerne den cache verlieren...
In der FPC RTL gibt es sogar

Code: Alles auswählen

 
procedure inclocked(var l : longint); inline;
 
begin
  if not ismultithread then
    inc(l)
   else
    cpuinclocked(l);
end;
 

Martin

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: "codepage aware ANSIStrings"

Beitrag von mschnell »

mse hat geschrieben:Meiner Meinung nach gehört Unicode Verarbeitung nicht in den Sprachumfang sondern in spezialisierte Bibliotheken,

Was meinst Du mit "Verarbeitung" ? Der Compiler muss nur die Codierung der Strings kennen, u.U. auch erkennen und - wenn nötig - Funktionen aus der RTL aufrufen, die eine Umcodierung vornehmen. Diese können wiederum - falls sinnvoll - externe Bibliotheken aufrufen.

mse hat geschrieben:Ich finde die FPC 2.6 Lösung Ideal,...

Ich finde sie sehr eingeschränkt. Und was (die aktuelle Version von) Lazarus daraus macht finde ich extrem verwirrend

mse hat geschrieben:Ein "code page aware AnsiString" ist überflüssig, es macht wirklich keinen Sinn dafür die Sprache zu komplizieren und die Performance für alle Programme zu verschlechtern.

- "überflüssig": dann ist Unicoide generell überflüssig und wir bleiben bei ANSI
- "komplizieren": wie meinst Du das ? (a) den Compiler aufwendiger gestalten oder (b) dem Anwender mehr Komplexität zumuten und dadurch auch mehr Möglichkeiten zu bieten ? "a" fände ich nicht schlimm und "b": der Anwender muss es ja nicht nutzen. Er kann auch beim der String-Codierung "default" bleiben (wie bei DXE üblich). Das Kapitel "Strings" in der Doku würde natürlich deutlich länger ;) .
- " Performance verschlechtern". Das halte ich für ein Gerücht. Die paar Assembler-Befehle, um im Bedarfsfall die String-Codierung zu überprüfen, sind vernachlässigbar. 8 Bit Strings brauchen (oft) weniger Speicherplatz und nutzen deshalb den Cache effektiver, 16 Bit Strings sind "deterministischer", was diverse Vorteile haben kann.

mse hat geschrieben:Wer in einem Programm verschiedene 8-Bit Codierungen verwendet macht sich sowieso ein massgeschneidertes System um beste Performance zu erreichen.

Programme müssen manchmal Dateien mit verschiedenen Codierungen verarbeiten und/oder APIs mit verschiedenen Codierungen bedienen. Manche Operationen lassen sich mit bestimmten Codierungen optimal durchführen. Dass muss auch keinesfalls 8 Bit sein. Außer locale-ANSI, UTF-8, UTF-16 und UTF32 sind auch noch andere (u.u. User-definierte) Codierungen denkbar, die ein perfektes System ebenfalls automatisiert handhabt.

mse hat geschrieben:Automatische Parallelverarbeitung/Multicore: Ich glaube das darf nicht überschätzt werden. Alle predigen man solle Parallelverarbeitung implementieren, die dann meist notwendigen Synchronisationsmechanismen darf man aber nicht verwenden, da dadurch alle Kerne den cache verlieren...


Da hast Du natürlich absolut recht. Eine "atomic" Cache-Synchronisation kann leicht so viel Performance wie tausende ASM-Befehle kosten.

Aber beispielsweise eine Matrix-Multiplikation braucht überhaupt keine Cache-Synchronisation (außer für die Abfrage der Fertigmeldung für jedes Ergebnis). Bei dieser sehr häufig vorkommenden Standard-Aufgabe und ähnlichen Aufgaben (FFT, Faltung, Projektion (Grafik), Kollisions-Berechnung, Kraftfelder, Schach (ist die Figur n bedoht), ...) steigt die Performance annähernd linear mit der Zahl der verwendeten Cores.

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: "codepage aware ANSIStrings"

Beitrag von mse »

mschnell hat geschrieben:
mse hat geschrieben:Meiner Meinung nach gehört Unicode Verarbeitung nicht in den Sprachumfang sondern in spezialisierte Bibliotheken,

Was meinst Du mit "Verarbeitung" ? Der Compiler muss nur die Codierung der Strings kennen, u.U. auch erkennen und - wenn nötig - Funktionen aus der RTL aufrufen, die eine Umcodierung vornehmen. Diese können wiederum - falls sinnvoll - externe Bibliotheken aufrufen.

Uppercase, lowercase, Sortierung, Kanonisierung (fully composed, fully decomposed).
mse hat geschrieben:Ein "code page aware AnsiString" ist überflüssig, es macht wirklich keinen Sinn dafür die Sprache zu komplizieren und die Performance für alle Programme zu verschlechtern.

- "überflüssig": dann fis Unicoide generell überflüssig und wir bleiben bei ANSI

???? Liest du denn überhaupt was ich schreibe? Dafür gibt es in FPC 2.6.2 ****UNICODESTRING**** !!!!
- "komplizieren": wie meinst Du das ? (a) den Compiler aufwendiger gestalten oder (b) dem Anwender mehr Komplexität zumuten und dadurch auch mehr Möglichkeiten zu bieten ? "a" fände ich nicht schlimm und "b": der Anwender muss es ja nicht nutzen. Er kann auch beim der String-Codierung "default" bleiben (wie bei DXE üblich). Das Kapitel "Strings" in der Duku würde natürlich deutlich länger ;) .

a und b.
- " Performance verschlechtern". Das halte ich für ein Gerücht. Die paar Assembler-Befehle um im Bedarfsfall die String-Codierung zu überprüfenb sind vernachlässigber.

Wenn du meinst. Vielleicht solltest du mal in die RTL schauen. ;-) Weisst du z.B. wieviel Bytes im 64bit Compiler die Speicherung von 'a' benötigt?
mse hat geschrieben:Wer in einem Programm verschiedene 8-Bit Codierungen verwendet macht sich sowieso ein massgeschneidertes System um beste Performance zu erreichen.

Programme müssen manchmal Dateien mit verschiedenen Codierungen verarbeiten und/oder APIs mit verschiedenen Codierungen bedienen. Manche Operationen lassen sich mit bestimmten Codierungen optimal durchführen. Dass muss auch keinesfalls 8 Bit sein. Außer locale-ANSI, UTF-8, UTF-16 und UTF32 sind auch noch andere (u.u. User-definierte) Codierungen denkbar, die ein perfektes System ebenfalls automatisiert handhabt.

Sage ich ja. Ausser "automatisch", da "automatisch" nicht gut genug ist.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: "codepage aware ANSIStrings"

Beitrag von mschnell »

mse hat geschrieben:
mschnell hat geschrieben: - " Performance verschlechtern". Das halte ich für ein Gerücht. Die paar Assembler-Befehle um im Bedarfsfall die String-Codierung zu überprüfenb sind vernachlässigber.

Wenn du meinst. Vielleicht solltest du mal in die RTL schauen. ;-) Weisst du z.B. wieviel Bytes im 64bit Compiler die Speicherung von 'a' benötigt?


0 Bytes solange es in einem Register steht :D :D :D

Wir sprachen vom Compiler, nicht von der RTL.

Natürlich hast Du recht, dass man die RTL auch betrachten muss. Die braucht natürlich jede Menge Performance, wenn tatsächlich umcodiert werden muss (und z.B. auch wenn zwei unterschiedlich codierte Strings verglichen werden). Da der Compiler aber nur dann eine Umcodierung anfordert wenn das tatsächlich nötig ist (der User das also (u.U. implizit) angefordert hat), passiert das nicht bei "jedem Programm", sondern nur bei einem, das wo es Sinn macht (oder der User sehr schwachsinnig programmiert). Im Normalfall liegen alle Strings in derselben Codierung vor (wenn der User immer die Default-Codierung anfordert, indem er nichts weiteres be der deklarastion der String-Variablen angibt). Dann ist die Performance natürlich von der Art der Codierung abhängig. Ein entsprechender "Default" in den Projekt-Optionen führt zu einem (beinahe) identischen Ablauf, als gäbe es keine "code aware Strings".

mse hat geschrieben: da "automatisch" nicht gut genug ist.

Warum nicht ?

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: "codepage aware ANSIStrings"

Beitrag von mse »

Die Frage nach dem 'a' habe ich schlecht formuliert. Weisst du wieviele Bytes zur Speicherung von 'a' in einem mit 64bit FPC trunk kompiliertem Programm als "code page aware AnsiString" benötigt werden?
Die komplizierten strings brauchen auch mehr Rechenleistung wenn nicht umcodiert werden muss. Bitte kompiliere die FPC trunk RTL mit debuginfo und steppe mit F7 und geöffnetem Assembler-Fenster durch den code dann siehst du es selbst. Wobei der overhead bereits beim "alten" AnsiString erschreckend ist.
Wenn jemand aus Performancegründen mit verschiedenen 8-bit Codierungen in einem Programm arbeitet, dann muss er oder sie genau wissen was vorgeht, "automatisch" ist dann exakt falsch.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: "codepage aware ANSIStrings"

Beitrag von mschnell »

Schaue ich mir mal an. Danke für den Hinweis.

Meine bisherigen Überlegungen (siehe englische Mailing Liste) gingen gegen das Argument, dass die Compiler-Unterstützung für die zusätzliche Einführung eines vollständig dynamischen code-aware Strings Types viel Performance gegenüber einem Systemm mit rein vordefinierten code aware Strings (wie DXE) kosten würde. Ein Unicode-System ganz ohne code awareness (das also mit einer einzigen festen Unicode Codierungsart arbeitet) habe ich dabei nicht betrachtet.

Ich kann mir kaum vorstellen, dass bei geschickter Programmierung die (gegenüber dem "alten" String Type) zusätzliche Verwaltung von zwei Worten für Code-Nummer und Code-Element-Länge (zusätzlich zu den ohnehin notwendigen Angaben Länge, Data-Pointer und Reference-Count) so viel ausmacht.

Du kannst da sicher auch für ein optimiertes Code-aware String System performantere Software schreiben <das meine ich überhaupt nicht sarkastisch, sondern in dem Bewusstsein, dass Du - im Gegensatz zu vielen anderen "Software viel-Schreibern" tiefgehende Analysen machst> .

mse hat geschrieben:"automatisch" ist dann exakt falsch.


"automatisch" bezieht eigentlich nur auf den Programmier-Stil. Statt bei allen Operationen die Codierungs-Art zu berücksichtigen (also immer wieder im Source-Code) wird das nur bei der Deklarierung der Variablen berücksichtigt.

Der Source-Code wird dann kürzer und lesbarer. Natürlich kann ein unüberlegter Programmierer dabei in eine Performance-Falle tappen, wenn er in einer Schleife versehentlich dauerndes Umcodieren erzwingt.

Ist aber unproblematisch wenn der Programmierer nicht selber solche Typen deklariert (wie gesagt, die RTL-API benutzt voll dynamische Typen und erzwingt keine besondere Codierung). Für Unbedarfte entsteht also gar kein Problem, wer solche speziellen Typen deklariert sollte wissen, was er tut. Und selbst wenn nicht wird seine Software korrekt funktionieren, nur eben nicht so flott wie es sein könnte. Das wiederum stört auch nur in seltenen Fällen, in denen dann eben genauer hingeschaut werden muss.

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: "codepage aware ANSIStrings"

Beitrag von mse »

mschnell hat geschrieben:Du kannst da sicher auch für ein optimiertes Code-aware String System performantere Software schreiben

Eben nicht, da die Verwendung von 8-bit string als universeller Speicher für Text und binäre Daten durch TBytes, TMarshaller und wer weiss was noch ersetzt wird.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: "codepage aware ANSIStrings"

Beitrag von mschnell »

Ich verstehe nicht, was Du mit "ersetzt wird" meinst.

- Passiert das irgendwie im Hintergrund und ist schlecht. Dann ist zu überlegen, ob man es nicht vermeiden kann.

- Ist das (aus Performance-Gründen) gut ? Dann ist zu überlegen, wann es greift und ob das relevant ist es also nicht schadet, da nicht mitzumachen .

Ich finde jedenfalls die Verwendung von (RawByte) Strings für binäre Daten viel praktischer als von anderen Strukturen, da man die normalen Operatoren wie "+" und "=" (Zuweisung und Vergleich) und "<"/">" (zum Sortieren verwenden kann, und Standard-Klassen wie TSringList (muss natürlich für uncodierte Byte-Strings in der RTL zur Verfügung stehen) nutzen kann. Und man muss sich durch das ref-couting nicht um Create() und Free() kümmern.

-Michael
Zuletzt geändert von mschnell am Do 31. Okt 2013, 12:54, insgesamt 1-mal geändert.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: "codepage aware ANSIStrings"

Beitrag von mse »

mschnell hat geschrieben:Ich verstehe nicht, was Du mit "ersetzt wird" meinst.

Z.B. in db.pas und überall in der Delphi RTL wo früher der alte string als Datenspeicher verwendet wurde.
Hier ist mehr zum Thema:
https://forums.embarcadero.com/thread.jspa?threadID=96205#610708

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: "codepage aware ANSIStrings"

Beitrag von mschnell »

Verstehe.
Statt die Strings ordentlich zu gestalten, damit sie ohne (gravierende) Nachteile wie bisher universell verwendet werden können, werden sie abgeschafft. Anscheinend gibt es beim neuen Compiler für ARM ja auch die gerade in Delphi eingeführten neuen Strings nicht. Finde ich eine saublöde Idee.

Muss man das mitmachen ?

Ich habe in meinem Vorschlag bisher noch keine gravierenden Nachteile (gegen die aktuellen Srtings in DXE ausmachen können. Und er erlaubt auch die Strings weiterhin für allgemeine (nicht-"druckbare Zeichen") Aufgaben ohne Einschränkungen und mit ordentlicher Performance zu verwenden.

-Michael

Antworten