Dateigröße <<< Speicherverbrauch
Dateigröße <<< Speicherverbrauch
Verständnisfrage: wenn ich eine Datei mit 4,8 GB in Kate öffne, schwillt der RAM-Verbrauch von ca.3 GB auf über 30 GB an und das Swap-Memory von 0 auf knappe 7 GB. Warum ist dem so, warum benötigt eine nicht komprimierte einfache Textdatei im RAM ein vielfaches der eigenen Größe? Beim Schliessen der Datei wächst die Auslagerungsdatei noch zusätzlich auf über 16 GB an.
Weiters: solange ich Kate nicht beende, bleibt die RAM- bzw. Swap-Auslastung bei 30+ bzw 16+ GB .,..
Das Verhalten ist übrigens bei KWrite fast exakt dasselbe: gleiche Dateigrößen, Anstieg des Memoryverbrauchs beim Dateischliessen und Verbleiben im Speicher.
Edit: Typo ausgebessert!
Weiters: solange ich Kate nicht beende, bleibt die RAM- bzw. Swap-Auslastung bei 30+ bzw 16+ GB .,..
Das Verhalten ist übrigens bei KWrite fast exakt dasselbe: gleiche Dateigrößen, Anstieg des Memoryverbrauchs beim Dateischliessen und Verbleiben im Speicher.
Edit: Typo ausgebessert!
Zuletzt geändert von kalamazoo am 23.09.2024 20:06:28, insgesamt 2-mal geändert.
Re: Dateigröße <<< Speicherverbrauch
Frag mal bei KDE nach was die sich dabei gedacht haben.
Re: Dateigröße <<< Speicherverbrauch
Der individuelle Speicherverbrauch eines Programms kann sehr unterschiedlich sein. Da Kate zum Programmieren und fuer normalerweise recht kleine Textdateien gemacht ist, waren Ueberlegungen zum Speicherverbrauch dabei vermutlich Nebensache. Ob man fuer eine typische Quellcodedatei ein Mehrfaches der Dateigroesse an Speicher verbraucht ist normalerweise voellig egal, da der Grundspeicherbedarf der Anwendung einen viel groesseren Einfluss hat. Bei einer so grossen Datei wie du sie oeffnest ist das dann voellig anders.
Sicherlich koennte man viel weniger Speicher verbrauchen, dann wird man aber manche Dinge in der Anwendung anders programmieren muessen. Nehmen wir beispielsweise an, dass Kate irgendeine Listen-Datenstruktur aus der Qt/KDE-Standard-Library fuer die Verwaltung der Zeilen der Datei verwendet, dann braucht die halt so viel Speicher wie sie braucht. Wenn Kate weniger verbrauchen will, dann muesste sie dafuer eigenen Code schreiben. Das lohnt sich nur wenn der Anwendungsfall relevant genug ist.
Das macht den Sachverhalten vielleicht verstaendlich. Ich weiss nicht, warum tatsaechlich so viel Speicher verbraucht wird. Das Beschriebene koennten nur moegliche Erklaerungen sein.
Auch wenn ich den Speicherverbrauch in dem Fall massiv finde, verwundert er mich nicht allzu sehr. So ein Programm ist nicht die beste Option fuer so eine Datei. Andere Programme werden viel weniger Speicher brauchen. Probier's z.B. mal mit Vim aus ... nur als Vergleichswert. Sicherlich gibt es auch speichersparendere grafische Editoren.
Sicherlich koennte man viel weniger Speicher verbrauchen, dann wird man aber manche Dinge in der Anwendung anders programmieren muessen. Nehmen wir beispielsweise an, dass Kate irgendeine Listen-Datenstruktur aus der Qt/KDE-Standard-Library fuer die Verwaltung der Zeilen der Datei verwendet, dann braucht die halt so viel Speicher wie sie braucht. Wenn Kate weniger verbrauchen will, dann muesste sie dafuer eigenen Code schreiben. Das lohnt sich nur wenn der Anwendungsfall relevant genug ist.
Das macht den Sachverhalten vielleicht verstaendlich. Ich weiss nicht, warum tatsaechlich so viel Speicher verbraucht wird. Das Beschriebene koennten nur moegliche Erklaerungen sein.
Auch wenn ich den Speicherverbrauch in dem Fall massiv finde, verwundert er mich nicht allzu sehr. So ein Programm ist nicht die beste Option fuer so eine Datei. Andere Programme werden viel weniger Speicher brauchen. Probier's z.B. mal mit Vim aus ... nur als Vergleichswert. Sicherlich gibt es auch speichersparendere grafische Editoren.
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Danke für die Erklärung, @Meillo, wird wohl so sein, aber eine fast 10-fache Größe erstaunt mich doch etwas ...
P.S. [diesmal an den Mod gerichtet]: aus irgendeinem unerfindlichen Grund scheint dieser Thread nicht unter "Eigene Beiträge" auf, sehr wohl aber unter "Neue Beiträge"; er wurde -- wie immer -- unter meinem Benutzernamen gepostet
"Kleiner-Als"-Zeichen im Titel? Bug?
EDIT: Benutzer kalamazoo spricht üblicherweise schwarz;
wenn er sich allerdings an die Mods wendet, dann spricht er rot
P.S. [diesmal an den Mod gerichtet]: aus irgendeinem unerfindlichen Grund scheint dieser Thread nicht unter "Eigene Beiträge" auf, sehr wohl aber unter "Neue Beiträge"; er wurde -- wie immer -- unter meinem Benutzernamen gepostet
"Kleiner-Als"-Zeichen im Titel? Bug?
EDIT: Benutzer kalamazoo spricht üblicherweise schwarz;
wenn er sich allerdings an die Mods wendet, dann spricht er rot
Zuletzt geändert von kalamazoo am 29.09.2024 15:36:09, insgesamt 1-mal geändert.
Re: Dateigröße <<< Speicherverbrauch
Zuerst mal möchte ich anmerken, dass kate einer der wenigen Editoren ist, der überhaupt mit so großen Dateien klar kommt und sogar noch flüssig scrollen kann. Das ist leider noch immer keine Selbstverständlichkeit. Sonst finde ich den Faktor gar nicht so viel. Deine Datei wird vermutlich in UTF-8 sein. Das mach zwar Speicherplatzeffizienz ganz nett sein, aber das Decoding ist teuer. Intern nutzt QT UTF-16. Damit verdoppelst du schon mal den Speicherverbrauch. Dann willst du relativ flott zwischen Zeilen/Wörtern/Zeichen springen können. Klassisch haben Editoren das gelöst indem man einfach jede Zeile auf die Längste mit Platz gefüllt hat. Das ist denke ich vorbei. Trotzdem: Da gehört mindestens noch irgend ein Index dran. Das gilt noch viel mehr für Klammern, Zeilennummern, dynamische Umbrüche Zwischen denen man springen muss... Annotationen für was gehighlighted werden muss fürs syntaxhighlighting, welche Farbe was hat, Historie für Änderungen. Da hängt bestimmt an jedem 10. Buchstaben nochmal eine Metainformation, die sicher mehr als 10 Byte hat. Da sind wir schon Faktor 4. und so geht es vermutlich weiter.. Am besten mit doppeltem Buffer, damit man zurück springen kann falls irgend eine Aktion schief geht und schon ist man bei 8...
Und dann bist du noch immer bei einem Text-Only Modus. Wenn der fürs flüssige Scrollen alles im voraus rendert... Ein Buchstabe hat sicher 24x12 Pixel a RGB pro Byte bist du schon bei Faktor ~1000. Klar kate wird sicher nur die nähere Umgebung im Vorraus rendern. Aber eventuell auch noch in irgend einer Vektorrepräsentation, damit man zoomen kann...
Und dann bist du noch immer bei einem Text-Only Modus. Wenn der fürs flüssige Scrollen alles im voraus rendert... Ein Buchstabe hat sicher 24x12 Pixel a RGB pro Byte bist du schon bei Faktor ~1000. Klar kate wird sicher nur die nähere Umgebung im Vorraus rendern. Aber eventuell auch noch in irgend einer Vektorrepräsentation, damit man zoomen kann...
Re: Dateigröße <<< Speicherverbrauch
Danke, @debra, für die detaillierte und erhellende Antwort! Dadurch ist mir einiges klarer geworden.
... und ich dachte immer: Datei öffnen heisst in etwa von der Platte 1:1 in den RAM oder halt 1:1+ aufgrund irgendeines Overheads ...
Ja, UTF-8, aber reiner ASCII-Text (irgendeine hypertrophierte Logdatei).
Geht Farbe in Kate überhaupt???debra hat geschrieben: ... welche Farbe was hat ..
... und ich dachte immer: Datei öffnen heisst in etwa von der Platte 1:1 in den RAM oder halt 1:1+ aufgrund irgendeines Overheads ...
Re: Dateigröße <<< Speicherverbrauch
Das kann man schon haben:kalamazoo hat geschrieben:27.09.2024 04:21:07... und ich dachte immer: Datei öffnen heisst in etwa von der Platte 1:1 in den RAM oder halt 1:1+ aufgrund irgendeines Overheads ...
Code: Alles auswählen
:-Q ls -lk /home/meillo/tmp/meillo.mbox
-rw------- 1 meillo meillo 340373 Sep 22 2012 /home/meillo/tmp/meillo.mbox
:-Q vim /home/meillo/tmp/meillo.mbox
[1] + Stopped vim /home/meillo/tmp/meillo.mbox
:-Q ps aux | egrep 'vim|USER'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
meillo 25817 1.4 4.6 421488 392444 pts/6 T 05:42 0:02 vim /home/meillo/tmp/meillo.mbox
meillo 26260 0.0 0.0 10176 1984 pts/2 S+ 05:44 0:00 egrep vim|USER
Es geht auch mit noch weniger:
Code: Alles auswählen
:-Q ed /home/meillo/tmp/meillo.mbox
348541308
^Z[2] + Stopped ed /home/meillo/tmp/meillo.mbox
:-Q ps aux | egrep 'ed /|USER'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
meillo 26510 8.8 0.5 97620 47548 pts/6 S+ 05:48 0:03 ed /home/meillo/tmp/meillo.mbox
meillo 26531 0.0 0.0 10176 1984 pts/2 S+ 05:48 0:00 egrep ed /|USER
Natuerlich ist ed auch nur ein Zeileneditor, aber prinzipiell koennten Vim oder Kate auch so aehnlich funktionieren: nur den aktuell angezeigten Teil der Datei laden ... bloss kann man dann halt kein globales Syntaxhighlighting und so Features haben und die Reaktionszeiten beim Scrollen und Springen in der Datei waeren langsamer. Luxusfeatures kosten nunmal Speicher ... und der Speicherverbrauch von Texteditoren ist selten fuer sehr grosse Dateien optimiert. Sie sind fuer das optimiert, fuer das sie zumeist eingesetzt werden.
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Die Erlaeuterungen von debra zeigen schoen, was alles damit noch zusammenhaengt.
Diese Aussage sehe ich allerdings anders:
Das Decoding ist eine reine Sache von (IMO vernachlaessigbarer) Rechenleistung und hat nichts mit dem Speicherverbrauch zu tun. Den Decoding-Unterschied koennte man im Zeitunterschied beim Oeffnen der Datei spueren. Jedoch werden dort andere Faktoren (wie die Qt-Bibliothek oder sonstige Initialisierungsarbeiten) vermutlich deutlich mehr Zeit brauchen und sich mehr von Programm zu Programm unterscheiden als die Unterschiede zwischen dem Dekodieren der unterschiedlichen Encodings. Darum meine ich, dass es vernachlaessigbar ist. Aber ich kenne dazu keine Messungen. Muesste das gleiche Programm mehrfach in einer Programmiersprache schreiben, die verschiedene Stringrepraesentationen unterstuetzt. Dann koennte man die Zeiten vergleichen.
Fuer den Speicherverbrauch ist relevant, welche Form der Stringkodierung die Programmiersprache, in der der Editor geschrieben ist, intern verwendet. Diese haben unterschiedlich viel Overhead. Ein ASCII-String in C hat 1 Byte Overhead pro Zeile. Ein ASCII-String in modernen Scriptsprachen, die meist UTF-16-Strings haben, hat zweimal die Anzahl der Zeichen plus einen Integer fuer die Laenge an Overhead pro Zeile. Der Speicherverbrauch zwischen einem C-Programm und einem Programm mit intern UTF-16-Strings verdoppelt sich also gleich schon mal ... insofern die Textdatei fast nur aus US-ASCII-Zeichen besteht. Bei griechischem Text beispielsweise sieht das aber gleich anders aus.
Diese Aussage sehe ich allerdings anders:
Das Decoding von UTF-8 ist zwar etwas teurer als das von UTF-16, aber keinesfalls teuer. Man muss halt in jedes Zeichenanfangs-Byte reinschauen, wieviele Folgebytes es hat und man muss aus jedem gelesenen Byte die relevanten Bits rausholen (das erfordert verschiedene billige Bitoperationen). Sicherlich werden auch noch Validitaetschecks gemacht. Bei UTF-16 muss man zwar keine einzelnen Bits der Bytes extrahieren und neu kombinieren -- man spart sich also ein paar Bitoperationen -- aber man muss in die Bytes ebenfalls reinschauen und sie validieren, da es unerlaubte Bitfolgen gibt. So gross kann ich mir den Unterschied beim Decoding nicht vorstellen. Hast du dazu Zahlen?debra hat geschrieben:27.09.2024 03:45:21Deine Datei wird vermutlich in UTF-8 sein. Das mach zwar Speicherplatzeffizienz ganz nett sein, aber das Decoding ist teuer.
Das Decoding ist eine reine Sache von (IMO vernachlaessigbarer) Rechenleistung und hat nichts mit dem Speicherverbrauch zu tun. Den Decoding-Unterschied koennte man im Zeitunterschied beim Oeffnen der Datei spueren. Jedoch werden dort andere Faktoren (wie die Qt-Bibliothek oder sonstige Initialisierungsarbeiten) vermutlich deutlich mehr Zeit brauchen und sich mehr von Programm zu Programm unterscheiden als die Unterschiede zwischen dem Dekodieren der unterschiedlichen Encodings. Darum meine ich, dass es vernachlaessigbar ist. Aber ich kenne dazu keine Messungen. Muesste das gleiche Programm mehrfach in einer Programmiersprache schreiben, die verschiedene Stringrepraesentationen unterstuetzt. Dann koennte man die Zeiten vergleichen.
Fuer den Speicherverbrauch ist relevant, welche Form der Stringkodierung die Programmiersprache, in der der Editor geschrieben ist, intern verwendet. Diese haben unterschiedlich viel Overhead. Ein ASCII-String in C hat 1 Byte Overhead pro Zeile. Ein ASCII-String in modernen Scriptsprachen, die meist UTF-16-Strings haben, hat zweimal die Anzahl der Zeichen plus einen Integer fuer die Laenge an Overhead pro Zeile. Der Speicherverbrauch zwischen einem C-Programm und einem Programm mit intern UTF-16-Strings verdoppelt sich also gleich schon mal ... insofern die Textdatei fast nur aus US-ASCII-Zeichen besteht. Bei griechischem Text beispielsweise sieht das aber gleich anders aus.
Use ed once in a while!
-
- Beiträge: 498
- Registriert: 24.09.2020 14:51:14
Re: Dateigröße <<< Speicherverbrauch
Im Text nicht, aber in der Darstellung – die Rede war von Syntaxhighlighting
--ks
Hier so: Debian Stable/Sid (nach Laune) – KDE Plasma – Lenovo Thinkpad T470p – i7-7700HQ – 32GB RAM
Re: Dateigröße <<< Speicherverbrauch
Ja bei allem außer ASCII ist UTF-16 ja platz effizienter als UTF-8. Du hast also das absolute worst case Szenario Ein „ (unteres Anführungszeichen) hat in UTF-8 drei Byte in UTF-16 nur zwei.kalamazoo hat geschrieben:27.09.2024 04:21:07Ja, UTF-8, aber reiner ASCII-Text (irgendeine hypertrophierte Logdatei).
Klar hebt dir den Platz zwischen Klammern hervor, unterstreicht dir falsch geschriebene Wörter...Geht Farbe in Kate überhaupt???
Und ich habe dir geschrieben, warum man das nicht macht.Datei öffnen heisst in etwa von der Platte 1:1 in den RAM oder halt 1:1+ aufgrund irgendeines Overheads ...
So gross kann ich mir den Unterschied beim Decoding nicht vorstellen. Hast du dazu Zahlen?
Code: Alles auswählen
time cat enwik9-16 | time uconv -f utf-16 -t utf-16 -x '::nfkc; [:Cc:] >; ::katakana-hiragana;'
time cat enwik9 | time uconv -f utf-8 -t utf-8 -x '::nfkc; [:Cc:] >; ::katakana-hiragana;'
Code: Alles auswählen
LANG=C.UTF-8 wc -m enwik9-ASCII
Code: Alles auswählen
LANG=C wc -m enwik9-ASCII
Code: Alles auswählen
Muesste das gleiche Programm mehrfach in einer Programmiersprache schreiben, die verschiedene Stringrepraesentationen unterstuetzt.
Aber es gibt keinen Editor mehr, der nur ASCII kann. Dann musst du mindestens wchars nehmen und dann bist du auch wieder bei UTF-16 oder irgend was ähnlichem...Ein ASCII-String in C hat 1 Byte Overhead pro Zeile.
Re: Dateigröße <<< Speicherverbrauch
Man muss hier genau hinschauen, was jeweils gemeint ist. Bei reinem US-ASCII braucht UTF-8 jeweils ein Byte, UTF-16 jeweils zwei Bytes. Bei deutschem Text (mit Umlauten und ß) braucht UTF-8 fuer die allermeisten Zeichen (die in US-ASCII enthalten sind) ein Byte und fuer ein paar Zeichen zwei Bytes. UTF-16 braucht immer zwei Bytes. UTF-8 braucht immer weniger Platz als UTF-16, ausser es enthaelt mehr 3-Byte-Zeichen als US-ASCII-Zeichen. Bei westeuropaeischen Texten ist das eigentlich nie der Fall. Das wirkt sich bei asiatischen Texten aus. In den anderen -- und so gut wie allen fuer Deutschsprachige relevanten -- Texten ist UTF-8 speichereffizienter als UTF-16.debra hat geschrieben:27.09.2024 08:23:12Ja bei allem außer ASCII ist UTF-16 ja platz effizienter als UTF-8. Du hast also das absolute worst case Szenario Ein „ (unteres Anführungszeichen) hat in UTF-8 drei Byte in UTF-16 nur zwei.kalamazoo hat geschrieben:27.09.2024 04:21:07Ja, UTF-8, aber reiner ASCII-Text (irgendeine hypertrophierte Logdatei).
Das stimmt. Bei US-ASCII muessen nur die Bytes gezaehlt werden. D.h. man kann auch jeweils 4096 Bytes auf einmal laden und den Counter um soviel erhoehen. Man muss noch nicht mal einzelne Bytes anschauen. Insofern man auf die Validitaetspruefung beim Lesen von UTF-16 verzichtet, koennte man das auch so machen. Aber ich vermute, dass UTF-16-Implementierungen die Bytes schon anschauen, ob sie valide sind. Dann muss man da jeweils zwei Bytes lesen, pruefen und zaehlen. Bei UTF-8 gibt das Start-Byte eines Zeichens an, wieviele Folgebytes es hat. D.h. man muss in das erste Byte eines Zeichen reinschauen. Die Folgebytes koennte man dann ueberspringen, oder eben validieren.debra hat geschrieben:27.09.2024 08:23:12So gross kann ich mir den Unterschied beim Decoding nicht vorstellen. Hast du dazu Zahlen?Macht bei mir 13% Unterschied. Ist also wirklich ziemlich vernachlässigbar. Das ist aber nur englischer Text und damit quasi nur ASCII und vor allem halt eine komplexe Operation. Relevant für kate dürfte eher Zeichen und Zeilen zählen sein. Leider kenne ich kein Tool das das auf die Schnelle macht. wc kann nur ASCII und UTF-8. Da sind die Unterschiede aber erheblich:Code: Alles auswählen
time cat enwik9-16 | time uconv -f utf-16 -t utf-16 -x '::nfkc; [:Cc:] >; ::katakana-hiragana;' time cat enwik9 | time uconv -f utf-8 -t utf-8 -x '::nfkc; [:Cc:] >; ::katakana-hiragana;'
braucht über 2sCode: Alles auswählen
LANG=C.UTF-8 wc -m enwik9-ASCII
unter einer ms.Code: Alles auswählen
LANG=C wc -m enwik9-ASCII
Aber du hast schon Recht, wenn man sich in einem UTF-8-String bewegt, dann man muss die Zeichen jeweils dekodieren, um zeichenweise navigieren zu koennen. Bei UTF-16 ... und allen Festbreitenkodierungen kann man direkt mit Vielfachen der Festbreite arbeiten. Wie fast immer hat alles Vor- und Nachteile und man muss sich entscheiden, welche Prioritaeten man hat.
Btw: Weiss zufaellig jemand, wie Runes in Go intern umgesetzt sind? Dort gibt es kein UTF-16 (weil die Erfinder von UTF-8 natuerlich wissen, dass es einfach besser ist als das schreckliche UTF-16 ) aber wie setzt man UTF-8-Strings intern um ohne viel Speicher zu verbrauchen?
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Nicht unbedingt Hieroglyphen und Smilies haben auch mal 4. Aber du hast halt einen Check ob das erste Bit 0 ist und kannst mehr oder weniger garantieren, dass der in 99.99% nicht genommen wird. Entsprechend werden da auch passende Sprungvorhersagen etc. gut funktionieren.UTF-16 jeweils zwei Bytes.
Ok. wc scheint das wirklich so dumm zu machen.Das stimmt. Bei US-ASCII muessen nur die Bytes gezaehlt werden
Deswegen etwas fairer:
Code: Alles auswählen
LANG=C time wc -w enwik9-ASCII
LANG=C.UTF-8 time wc -w enwik9-ASCII
Da das Programm das Byte ja selber schreibt, braucht man das eher nicht validieren. Aber du hast halt bei UTF-8 quasi immer 4 verschiedene Varianten für die du dann noch für alles, was nicht ASCII ist, Bits masken und shiften musst. Bei UTF-16 ist das quasi ausschließlich für Smilies der Fall. Sonst hast du direkt dein Unicode. Selbst alle Zeichen auf sina.com.cn liegen noch im 2-Byte Bereich von UTF-16 nur Obskuritäten wie die Dame🨁sind komplexer. Da kannst du dir fast schon Annotation an deine Strings machen, ob die noch UCS-2 sind, und die wichtigsten Funktionen doppelt implementieren.Die Folgebytes koennte man dann ueberspringen, oder eben validieren.
Re: Dateigröße <<< Speicherverbrauch
Kann ich mir nicht erklaeren. Aus meiner Sicht sollten beide Varianten gleich schnell sein, da Whitespace in beiden Faellen identisch definiert sein sollte: Entweder nur bestimmte Zeichen aus US-ASCII oder ggf. abhaengig vom Locale. US-ASCII-Zeichen sehen in US-ASCII-Text gleich aus wie in UTF-8-Text.debra hat geschrieben:27.09.2024 13:05:04Und dann ist die UTF-8 Variante zuverlässig ~30% schneller. Warum?!Code: Alles auswählen
LANG=C time wc -w enwik9-ASCII LANG=C.UTF-8 time wc -w enwik9-ASCII
Manpage wc(1) hat geschrieben: A word is a non-zero-length sequence of characters delimited by white space.
What?! Dann hat man ja das Schlechte aus beiden Welten. Das macht doch konzeptionell gar keinen Sinn. UTF-16 ist nur dann sinnvoll, wenn es ein Festbreitenencoding ist und das erzwingt, dass es nur eine begrenzte Menge an Zeichen abbilden kann. Welche Menge das ist, ist ein Kompromis zwischen Menge der Zeichen und Speicherverbrauch. Wenn man das durch eine doch variable Zeichenlaenge aufbricht, dann kann man doch gleich UTF-8 nehmen, welches so gut wie immer weniger Speicher braucht, technisch 31-Bit fuer die Zeichenkodierung genutzt werden koennen, und es vor allem keine schrecklichen Byte-Order-Probleme gibt, plus weitere Vorteile wie erkennen zu koennen, ob man sich am Anfang oder in der Mitte eines Mehrbytezeichens befindet. Wenn UTF-16 kein Festbreitenencoding mehr ist, dann verliert es seinen einzigen Vorteil.debra hat geschrieben:27.09.2024 13:05:04Bei UTF-16 ist das quasi ausschließlich für Smilies der Fall. Sonst hast du direkt dein Unicode. Selbst alle Zeichen auf sina.com.cn liegen noch im 2-Byte Bereich von UTF-16 nur Obskuritäten wie die Dame🨁sind komplexer. Da kannst du dir fast schon Annotation an deine Strings machen, ob die noch UCS-2 sind, und die wichtigsten Funktionen doppelt implementieren.
Du siehst, ich bin ein entschiedener Gegner von UTF-16. Es ist zwar auf den ersten Blick einfach und pragmatisch, auf den genaueren Blick aber in vielerlei Weise problematisch.
(Nachtrag: Mir war gar nicht bewusst, dass UTF-16 kein Festbreitenencoding ist. Mit diesem Wissen finde ich es noch viel schlechter als zuvor. Ich sehe keinen einzigen Grund, warum UTF-16 sinnvoll sein soll. In den meisten Faellen ist UTF-8 besser und in ein paar Faellen ist UTF-32 besser, aber UTF-16 ist nie das beste Verfahren.)
Zuletzt geändert von Meillo am 28.09.2024 07:31:26, insgesamt 1-mal geändert.
Grund: Nachtrag
Grund: Nachtrag
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Dazu habe ich nun nachgelesen:Meillo hat geschrieben:27.09.2024 09:11:27Btw: Weiss zufaellig jemand, wie Runes in Go intern umgesetzt sind?
Man kann sich in Go also aussuchen, ob man mit den Bytes des Strings arbeiten will oder mit den (dekodierten) Zeichen (Runes).https://go.dev/blog/strings hat geschrieben: In Go, a string is in effect a read-only slice of bytes.
[...]
As implied up front, indexing a string accesses individual bytes, not characters.
[...]
The Go language defines the word rune as an alias for the type int32 [...]
[...]
Besides the axiomatic detail that Go source code is UTF-8, there’s really only one way that Go treats UTF-8 specially, and that is when using a for range loop on a string.
We’ve seen what happens with a regular for loop. A for range loop, by contrast, decodes one UTF-8-encoded rune on each iteration. Each time around the loop, the index of the loop is the starting position of the current rune, measured in bytes, and the code point is its value. Here’s an example using yet another handy Printf format, %#U, which shows the code point’s Unicode value and its printed representation:
const nihongo = "日本語"
for index, runeValue := range nihongo {
fmt.Printf("%#U starts at byte position %d\n", runeValue, index)
}
The output shows how each code point occupies multiple bytes:
U+65E5 '日' starts at byte position 0
U+672C '本' starts at byte position 3
U+8A9E '語' starts at byte position 6
Runes sind 4 Bytes lang (also wie in einem UTF-32-Encoding). Es ist optional in Go, einen String in ein Slice (=Array) von Runes zu konvertieren, ebenso gut kann man on-the-fly das UTF-8 dekodieren oder direkt auf den Bytes arbeiten.
Was das fuer das einen Texteditor in Go bedeutet, ist eine interessante Frage. Es wird wie immer sein: man kann Speicherverbrauch gegen Rechenzeit tauschen und umgekehrt, je nachdem was einem im jeweiligen Fall wichtiger ist.
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Perl macht das glaube ich sogar mit 1-Byte. Jeder String bekommt ein custom-encoding in dem alle Zeichen drin sind. Gibt es mehr als 255 unterschiedliche wird der String intern geteilt. Zumindest abseits von China rasend schnell aber ein Pain das verständlich zu implementieren.wenn es ein Festbreitenencoding ist und das erzwingt, dass es nur eine begrenzte Menge an Zeichen abbilden kann. Welche Menge das ist, ist ein Kompromis zwischen Menge der Zeichen und Speicherverbrauch.
Auf der überwältigenden Mehrheit der Systeme sind int32 Operationen deutlich schneller als Byte Operationen. Die willst du nutzen. Du musst also sowieso bitbanging machen. Bei UTF-16 fallen die Buchstabengrenzen halt fast immer auf int32 Grenzen. Es kann einen super speziellen Fall geben. Aber der kommt halt fast nie vor. Der Test darauf ist sehr billig und die Sprungvorhersage optimiert dir alles andere raus. Bei UTF-8 ist der Test wie lange ein Zeichen ist, deutlich teurer und der Fall dass ein Zeichen über ein int hinaus läuft alles andere als ein absoluter Edge Case.Wenn man das durch eine doch variable Zeichenlaenge aufbricht, dann kann man doch gleich UTF-8 nehmen
Alles Sachen, die relevant für ein Dateiformat/Austauschencoding sind. Deswegen will QT und Go nur noch UTF-8-Strings im Source. Für deine interne Repräsentation ist dir das vollständig Wurst: Du schreibst die Strings selbst. In der Byte-Order die du gewählt hast und in dem Alighnment, dass du für richtig hältst. In Hardware wird intern vermutlich eh in 32Bit Blöcken oder größer gearbeitet... Da musst du dir ganz andere Gedanken machen.und es vor allem keine schrecklichen Byte-Order-Probleme gibt, plus weitere Vorteile wie erkennen zu koennen, ob man sich am Anfang oder in der Mitte eines Mehrbytezeichens befindet.
Achtung Wörter können nicht nur durch Leerzeichen getrennt sein, sondern auch durch / oder Punkt und Zeilenumbruch... Das Problem ist eine Nummer komplexer. In UTF-8 ist die Auswahl deutlich größer als in ASCII. Man sollte also annehmen, dass der Abgleich deutlich länger geht. Das Programm weiß ja nicht, dass im Text nur ASCII vorkommt und muss deswegen auch gegen – und nicht nur gegen - abgleichen – Auch wenn das in der Realität nie vorkommt.da Whitespace in beiden Faellen identisch definiert sein sollte: Entweder nur bestimmte Zeichen aus US-ASCII oder ggf. abhaengig vom Locale. US-ASCII-Zeichen sehen in US-ASCII-Text gleich aus wie in UTF-8-Text.
Real ist das extrem selten der Fall. Auch wenn deine 32Bit-Zeichen wunderbar zu deinen 32Bit Operationen passen und so relativ naheliegend performante Implementierungen ergeben. SIMD ist ein Ding und wird bei Stringverarbeitung massiv eingesetzt. Da bekommst du halt nur halb so viele Zeichen pro Tankt verarbeitet. Deine Register haben eine bestimmte Größe. Genau so dein Cache und dein RAM und deine RAM Zeilen... Mehr Daten führt quasi immer zu langsameren Verarbeitungszeiten. Deine UCS-4-Runes werden vermutlich überall abseits von Sprüngen mit fester Buchstabenlänge über sehr viele Zeichen beschissen performen. Oft ist das komplexere Programm eben doch das schnellere: UTF-16 bietet halt in den aller meisten Fällen eine genau so primitive Implementierung wie UCS-4 wird aber wegen den Operationen auf deutlich kleineren Datenmengen deutlich schneller sein. Es benötigt immer einen hässlich komplexen Special-Case, der aber einfach erkannt werden kann und so gut wie nie vorkommt. – So ändert er fast nichts an der durchschnittlichen Laufzeit. Das hast du halt bei UTF-8 nicht mehr: Prüfst du stumpf auf erstes Bit 1 kommt das doch recht regelmäßig vor und die Behandlung danach wird ungleich komplexer.Es wird wie immer sein: man kann Speicherverbrauch gegen Rechenzeit tauschen und umgekehrt, je nachdem was einem im jeweiligen Fall wichtiger ist.
Re: Dateigröße <<< Speicherverbrauch
Nachdem dieser Faden bei mir nicht unter "Eigene Beiträge" aufscheint, ist er ein wenig dem Blickfeld entschwunden -- ich könnte aber auf dem derzeitigen Niveau ohnedies nichts wirklich Sinnvolles beitragen. Chapeau @debra und @Meillo!
P.S. (weil es so iiiiiiirgendwieee dazupasst): ich habe mittlerweile mein altes Problem mit der Zeichendarstellung in KDE-Plasma lösen können (viewtopic.php?p=1371860); die Lösung ist simpel, ... wenn man weiss wie es geht
Danke, bin gerade vom Schlauch heruntergestiegenkreuzschnabel hat geschrieben:27.09.2024 07:08:14Im Text nicht, aber in der Darstellung – die Rede war von Syntaxhighlighting
P.S. (weil es so iiiiiiirgendwieee dazupasst): ich habe mittlerweile mein altes Problem mit der Zeichendarstellung in KDE-Plasma lösen können (viewtopic.php?p=1371860); die Lösung ist simpel, ... wenn man weiss wie es geht
Re: Dateigröße <<< Speicherverbrauch
In diese Richtung habe ich auch noch ein bisschen gedacht, als du zuvor schon erwaehnt hast, dass man in der Sprache unterschiedliche Strings unterschiedlich encoden kann. Beim Beispiel Texteditor koennte man folglich jede Zeile mit einem anderen Festbreitenencoding ablegen. Also wenn sie nur US-ASCII-Zeichen enthaelt, dann nehmen wir ein Byte pro Zeichen, wenn mehr noetig ist, dann fuer die BMP sowas wie UTF-16 (aber ohne die Erweiterung mit variabler Zeichenlaenge), und fuer den Rest UTF-32. Der Editor haette dann einen recht kleinen Speicherverbrauch, koennte immer mit Festbreitenencodings arbeiten, und muesste nur hin und wieder eine Zeile umcodieren. Das Umcodieren waere in dem Fall aber nicht so schlimm, weil man beim ``Hochkodieren'' einfach nur Null-Bytes einfuegen muesste, die man beim ``Runterkodieren'' die Zusatzbytes einfach entfernen kann, wenn sie im ganzen String alle null sind. Das waere eine nette Programmieraufgabe, das mal auszuprobieren, ob das so machbar waere. (Schade, dass ich kein Student mit viel Zeit mehr bin.)debra hat geschrieben:28.09.2024 17:53:48Perl macht das glaube ich sogar mit 1-Byte. Jeder String bekommt ein custom-encoding in dem alle Zeichen drin sind. Gibt es mehr als 255 unterschiedliche wird der String intern geteilt. Zumindest abseits von China rasend schnell aber ein Pain das verständlich zu implementieren.wenn es ein Festbreitenencoding ist und das erzwingt, dass es nur eine begrenzte Menge an Zeichen abbilden kann. Welche Menge das ist, ist ein Kompromis zwischen Menge der Zeichen und Speicherverbrauch.
Das mit den int-Grenzen ueberzeugt mich.debra hat geschrieben:28.09.2024 17:53:48Du musst also sowieso bitbanging machen. Bei UTF-16 fallen die Buchstabengrenzen halt fast immer auf int32 Grenzen. Es kann einen super speziellen Fall geben. Aber der kommt halt fast nie vor. Der Test darauf ist sehr billig und die Sprungvorhersage optimiert dir alles andere raus. Bei UTF-8 ist der Test wie lange ein Zeichen ist, deutlich teurer und der Fall dass ein Zeichen über ein int hinaus läuft alles andere als ein absoluter Edge Case.
Was mich nicht ueberzeugt ist, dass der Test bei UTF-8 deutlich teurer waere. Natuerlich muss man da in jedes Byte reinschauen, aber bei UTF-16 muss man das auch! Dass die ``erweiterten'' Zeichen bei UTF-16 nur sehr selten vorkommen, aendert nichts am Aufwand, denn jedes Zeichen koennte ein solches erweitertes Zeichen sein, auch wenn es dann tatsaechlich so gut wie nie der Fall ist. Den Aufwand, bei jedem Zeichen trotzdem reinschauen zu muessen, reduziert sich dadurch nicht. Das waere anders wenn UTF-16 tatsaechlich ein Festbreitenencoding waere. Somit ist aus meiner Sicht der Aufwand in beiden Faellen vergleichbar. Aber fuehre gerne nochmal aus, was genau bei UTF-8 diesbezueglich teurer sein soll als bei UTF-16.
Zustimmung.debra hat geschrieben:28.09.2024 17:53:48Alles Sachen, die relevant für ein Dateiformat/Austauschencoding sind. Deswegen will QT und Go nur noch UTF-8-Strings im Source. Für deine interne Repräsentation ist dir das vollständig Wurst: Du schreibst die Strings selbst. In der Byte-Order die du gewählt hast und in dem Alighnment, dass du für richtig hältst.und es vor allem keine schrecklichen Byte-Order-Probleme gibt, plus weitere Vorteile wie erkennen zu koennen, ob man sich am Anfang oder in der Mitte eines Mehrbytezeichens befindet.
Im Falle von wc(1) ist definiert, dass nur Whitespace Woerter trennt:debra hat geschrieben:28.09.2024 17:53:48Achtung Wörter können nicht nur durch Leerzeichen getrennt sein, sondern auch durch / oder Punkt und Zeilenumbruch...da Whitespace in beiden Faellen identisch definiert sein sollte: Entweder nur bestimmte Zeichen aus US-ASCII oder ggf. abhaengig vom Locale. US-ASCII-Zeichen sehen in US-ASCII-Text gleich aus wie in UTF-8-Text.
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/wc.html hat geschrieben: The wc utility shall consider a word to be a non-zero-length string of characters delimited by white space.
[...]
LC_CTYPE
Determine the locale for the interpretation of sequences of bytes of text data as characters (for example, single-byte as opposed to multi-byte characters in arguments and input files) and which characters are defined as white-space characters.
[...]
Some historical implementations use only <space>, <tab>, and <newline> as word separators. The equivalent of the ISO C standard isspace() function is more appropriate.
Du schreibst, dass weniger Daten schneller verarbeitet werden wuerden als mehr Daten (2 Bytes schneller als 4 Bytes), zugleich schreibst du, dass mehr Daten schneller verarbeitet werden wuerde als weniger (2 Bytes schneller als 1 Byte). Das verstehe ich nicht recht.debra hat geschrieben:28.09.2024 17:53:48Real ist das extrem selten der Fall. Auch wenn deine 32Bit-Zeichen wunderbar zu deinen 32Bit Operationen passen und so relativ naheliegend performante Implementierungen ergeben. SIMD ist ein Ding und wird bei Stringverarbeitung massiv eingesetzt. Da bekommst du halt nur halb so viele Zeichen pro Tankt verarbeitet. Deine Register haben eine bestimmte Größe. Genau so dein Cache und dein RAM und deine RAM Zeilen... Mehr Daten führt quasi immer zu langsameren Verarbeitungszeiten. Deine UCS-4-Runes werden vermutlich überall abseits von Sprüngen mit fester Buchstabenlänge über sehr viele Zeichen beschissen performen. Oft ist das komplexere Programm eben doch das schnellere: UTF-16 bietet halt in den aller meisten Fällen eine genau so primitive Implementierung wie UCS-4 wird aber wegen den Operationen auf deutlich kleineren Datenmengen deutlich schneller sein. Es benötigt immer einen hässlich komplexen Special-Case, der aber einfach erkannt werden kann und so gut wie nie vorkommt. – So ändert er fast nichts an der durchschnittlichen Laufzeit. Das hast du halt bei UTF-8 nicht mehr: Prüfst du stumpf auf erstes Bit 1 kommt das doch recht regelmäßig vor und die Behandlung danach wird ungleich komplexer.Es wird wie immer sein: man kann Speicherverbrauch gegen Rechenzeit tauschen und umgekehrt, je nachdem was einem im jeweiligen Fall wichtiger ist.
UTF-8-Text, der typischerweise in Editoren verarbeitet wird, besteht in UTF-8 sicherlich zu mehr als 90% aus 1-Byte-Zeichen und dann noch ein paar 2-Byte-Zeichen. 3- und 4-Byte-Zeichen sind in UTF-8 wahrscheinlich aehnlich selten wie die erweitereten 4-Byte-Zeichen in UTF-16.
Ich verstehe nicht recht, warum du der Meinung bist, dass Computer 16-Bit-Einheiten schneller verarbeiten koennten als sowohl 8-Bit- als auch 32-Bit-Einheiten. Was ist so magisch an den 16-Bits?
Was ich verstehe ist der Alignment-Aspekt, der mit UTF-16 meist und mit UTF-32 immer erreicht wird, mit UTF-8 aber etwas weniger oft (jedoch immer noch oft, da rund 90% der Zeichen 1-Byte-Zeichen sein werden, die immer alignen).
Ich werde in den naechsten Tagen ein kleines Programm schreiben, das Textdateien analysiert, wieviele Multi-Byte-Zeichen sie enthalten und inwiefern sie alignen, um dafuer mal Zahlen aus der Praxis zu bekommen. Falls jemand dazu bereits gemachte Auswertungen kennt, bitte verlinken.
Zuletzt geändert von Meillo am 01.10.2024 10:25:32, insgesamt 1-mal geändert.
Grund: Kleine Anpassung
Grund: Kleine Anpassung
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Der Test ist nur viel einfacher: !(char^0x8000) ist ein sehr einfacher Test der dir direkt die zwei möglichen Varianten generiert: Nachfolgendes int32 muss mit einem einzelnen rotieren der vorderen 16Bits und nem Tausch der beiden int16 decoded werden. (Zwei Operationen.) Oder kann als int16 kann direkt verwendet werden. Ein !(char^0x80008000) cleared dich direkt für die beiden Zeichen.Meillo hat geschrieben:01.10.2024 08:40:04Natuerlich muss man da in jedes Byte reinschauen, aber bei UTF-16 muss man das auch!
!(char^0x80) sagt dir erst mal noch wenig: Klar wenn es gut geht ist es ASCII. Aber sonst: wird es sehr komplex. Und wie gesagt: Das ist um Größenordnungen häufiger. Wenn du 90% ASCII hast, dann hast du in 18% der Fälle einen anderen Fall, als im vorherigen Durchlauf. Bei UTF-16 kannst du selbst bei chinesischen Texten davon ausgehen, dass du eher bei 99.999% der Fälle bist. Multiplizierst du das mit der Wahrscheinlichkeit, dass zwei Zeichen auf einmal UTF-8 sind bist du bei 33% Fehlschalgsrate. 90% ASCII ist natürlich hart untertrieben. Aber wenn du bedenkst dass eine fehlgeschlagene Sprungvorhersage gerne mal ein zwanzigfaches kostet, wird das böse, wenn nur wenige Prozent fehl schlagen.
Deswegen haben wir spekulative Ausführung. Der Rechner nimmt erst mal an, dass es nicht der Fall ist, und macht dann extrem teuer eine Rolle rückwärts, wenn es doch der Fall ist.Dass die ``erweiterten'' Zeichen bei UTF-16 nur sehr selten vorkommen, aendert nichts am Aufwand, denn jedes Zeichen koennte
Man kann sie oft so behandeln: Zwei aufeinander folgende Bytes die mit 0 anfangen sind sicher exakt ein Zeichen. Zwei aufeinander folgende Bytes, die mit 0 anfangen sind in UTF-8 eben mal 2 Zeichen mal 1.5 mal 1⅓.…. Ein einzelnes Byte, dass mit null anfängt, ist mal ein Zeichen, mal 1.5, mal...Das waere anders wenn UTF-16 tatsaechlich ein Festbreitenencoding waere. Somit ist aus meiner Sicht der Aufwand in beiden Faellen vergleichbar. Aber fuehre gerne nochmal aus, was genau bei UTF-8 diesbezueglich teurer sein soll als bei UTF-16.
Grundsätzlich: Mehr Daten ist meistens langsamer: Mehr Code auch. Im Vergleich zu UCS-4 hat UTF-16 halb so viel Daten und minimal mehr Code, der real ausgeführt wird. Das ist kein fair Match. UTF-8 hat im Vergleich zu UTF-16 auch halb so viel Daten aber halt deutlich mehr Code.debra hat geschrieben:28.09.2024 17:53:48Du schreibst, dass weniger Daten schneller verarbeitet werden wuerden als mehr Daten (2 Bytes schneller als 4 Bytes), zugleich schreibst du, dass mehr Daten schneller verarbeitet werden wuerde als weniger (2 Bytes schneller als 1 Byte). Das verstehe ich nicht recht.
Nein. Alle Smilies, quasi alle chinesischen Zeichen, die meiste Punktuation ist 3-Byte aber in UTF-16 nur 2. Es gibt kein Unicode Zeichen dass in das in UTF-16 4 Byte braucht aber in UTF-8 nur 3, da hinter den Chinesischen Zeichen ein Loch gelassen wurde, dass dann für die Erweiterungen nicht gereicht hat. Reiner deutsche Fließtext dürfte etwas anders aussehen. Ist aber sicher nicht repräsentativ.3- und 4-Byte-Zeichen sind in UTF-8 wahrscheinlich aehnlich selten wie die erweitereten 4-Byte-Zeichen in UTF-16.
Weil die Prozesor Hersteller machen halt Statistiken machen, was am häufigsten genutzt wird. Da ist 32 halt ganz vorne und dann 64 und 16Bit. Byte Operationen nicht. Entsprechend optimieren sie ihre Prozessoren, dass die Operationen in einem Takt durch laufen. Passend macht das gcc mit -march=znver3 -O3 bei mir ausIch verstehe nicht recht, warum du der Meinung bist, dass Computer 16-Bit-Einheiten schneller verarbeiten koennten als sowohl 8-Bit- als auch 32-Bit-Einheiten. Was ist so magisch an den 16-Bits?
Code: Alles auswählen
volatile int64_t c=12;
uint8_t b=c;
uint8_t a=7;
a+=b;
a*=b;
Code: Alles auswählen
lea 0x7(%rdx),%eax
imul %edx,%eax
movzbl %al,%eax
Wenn du jetzt performanten UTF-16 Code schreiben willst, verarbeitet der immer 2 16Bit-Zeichen auf einmal. Was quasi immer funktioniert. Performanter UTF-8 Code versucht vermutlich 4 8Bit-Zeichen zu nehmen. Das funktioniert dann bei weitem nicht mehr so oft: Bei 90% ASCII und je 5% 2Byte und 3Byte UTF-8 bist du nur noch bei 56%, dass das gut geht. => Deine Sprungerkennung geht relativ häufig kaputt...
Re: Dateigröße <<< Speicherverbrauch
Zuerstmal habe ich den vorherigen Beitrag lesbar gemacht. Sonst habe ich mal eine Statistiken zu den Namen, die in der Weltkarte von Osmand auftauchen. (Ich habe vorher uniq drüber laufen lassen, weil viele Flüsse etc in viele gleichnamige Teile aufgeteilt sind.)
Insgesamt 21717221 Zeichen.
Davon
Es scheint also doch Zeichen zu geben, die 3-Byte in UTF-8 haben und 4 in UTF-16. Eventuell ist da aber auch schlicht ein fehlerhaft codiertes Zeichen im Datensatz.
Klar das ist Natürlich ein bisschen fies, weil anteilig viel mehr Texte in englisch/Programmiersprachen... geschrieben sind als Straßennahmen. Aber auch wenn die Weltübersicht das vermutlich weitestgehend Nivelliert, dürfte Europa+Russland und Amerika weit überrepräsentiert sein, die alle in erster Linie 2-Byte encodings nutzen. Während in Afrika, Naher Osten und Asien inklusive allen drei CYK-länder fast keine Änderungen pro Einwohner haben.
Insgesamt 21717221 Zeichen.
Davon
Code: Alles auswählen
17957426 ( 83%) ASCII
2616854 ( 12%) 2-Byte UTF-8
1142629 ( 5%) 3-byte UTF-8
312 (.01‰) 4-Byte UTF-8
313 (.01‰) 4-byte UTF-16
21716908 (100%) 2-Byte UTF-16
5682050 ( 26%) H, die ich als Trennzeichen verwendet habe
Klar das ist Natürlich ein bisschen fies, weil anteilig viel mehr Texte in englisch/Programmiersprachen... geschrieben sind als Straßennahmen. Aber auch wenn die Weltübersicht das vermutlich weitestgehend Nivelliert, dürfte Europa+Russland und Amerika weit überrepräsentiert sein, die alle in erster Linie 2-Byte encodings nutzen. Während in Afrika, Naher Osten und Asien inklusive allen drei CYK-länder fast keine Änderungen pro Einwohner haben.
Re: Dateigröße <<< Speicherverbrauch
So, endlich antworte ich hier.
Diese lassen sich in UTF-8 in 3 Bytes kodieren, in UTF-16 brauchen aber nicht in 2 Bytes.
Bei diesen Daten braucht UTF-16 deutlich mehr Speicher als UTF-8, naemlich 63% mehr.
Ich vermute, dass dies bei fast allen Texten im Internet so sein wird, solange man nicht ausschliesslich in ostasiatischen Sprachraeumen unterwegs ist.
Das ``sehr komplex'' sind auch nur Bitoperationen, zusaetzlich zum obigen noch Shifts. Das wuerde ich nicht komplexer nennen, aber ich stimme zu, dass es der Prozess insgesamt aufaendiger ist. Vielleicht geht es dir auch vor allem um die Fallunterscheidungen, die oefters vorkommen als bei UTF-16.debra hat geschrieben:01.10.2024 23:50:29Der Test ist nur viel einfacher: !(char^0x8000) ist ein sehr einfacher Test der dir direkt die zwei möglichen Varianten generiert: Nachfolgendes int32 muss mit einem einzelnen rotieren der vorderen 16Bits und nem Tausch der beiden int16 decoded werden. (Zwei Operationen.) Oder kann als int16 kann direkt verwendet werden. Ein !(char^0x80008000) cleared dich direkt für die beiden Zeichen.Meillo hat geschrieben:01.10.2024 08:40:04Natuerlich muss man da in jedes Byte reinschauen, aber bei UTF-16 muss man das auch!
!(char^0x80) sagt dir erst mal noch wenig: Klar wenn es gut geht ist es ASCII. Aber sonst: wird es sehr komplex. Und wie gesagt: Das ist um Größenordnungen häufiger.
Meiner Recherche nach brauchen Emojis in beiden Encodings 4 Bytes und was ich unter Punktuation verstehe ist grossteils in US-ASCII enthalten, aber was die chinesischen Zeichen angeht (die hier relevanter sind als Emojis), hast du Recht.debra hat geschrieben:01.10.2024 23:50:29Nein. Alle Smilies, quasi alle chinesischen Zeichen, die meiste Punktuation ist 3-Byte aber in UTF-16 nur 2.3- und 4-Byte-Zeichen sind in UTF-8 wahrscheinlich aehnlich selten wie die erweitereten 4-Byte-Zeichen in UTF-16.
debra hat geschrieben:01.10.2024 23:50:29Deswegen haben wir spekulative Ausführung. Der Rechner nimmt erst mal an, dass es nicht der Fall ist, und macht dann extrem teuer eine Rolle rückwärts, wenn es doch der Fall ist.
Danke fuer die Erklaerungen der hardwarenahen Dinge. Da kenne ich mich nicht so gut aus. Was du beschreibst, ueberzeugt mich.debra hat geschrieben:01.10.2024 23:50:29Weil die Prozesor Hersteller machen halt Statistiken machen, was am häufigsten genutzt wird. Da ist 32 halt ganz vorne und dann 64 und 16Bit. Byte Operationen nicht. Entsprechend optimieren sie ihre Prozessoren, dass die Operationen in einem Takt durch laufen.
Danke fuer diese Auswertung. Zu meinem Testprogramm bin ich noch nicht gekommen. Aber du hast das ja schon optimal gemacht. Kannst du den Code des Programms hier posten? Ich wuerde es gerne mal auf deutsche, franzoesische und chinesische Wikipediaseiten anwenden.debra hat geschrieben:03.10.2024 22:07:55Sonst habe ich mal eine Statistiken zu den Namen, die in der Weltkarte von Osmand auftauchen. (Ich habe vorher uniq drüber laufen lassen, weil viele Flüsse etc in viele gleichnamige Teile aufgeteilt sind.)
Insgesamt 21717221 Zeichen.
DavonCode: Alles auswählen
17957426 ( 83%) ASCII 2616854 ( 12%) 2-Byte UTF-8 1142629 ( 5%) 3-byte UTF-8 312 (.01‰) 4-Byte UTF-8 313 (.01‰) 4-byte UTF-16 21716908 (100%) 2-Byte UTF-16 5682050 ( 26%) H, die ich als Trennzeichen verwendet habe
Zumindest *ein* Zeichen kann in 2-Byte-Zeichen in UTF-16 nicht kodiert werden, denn eine Codestelle muss reserviert sein, um markieren zu koennen, dass dies ein 4-Byte-Zeichen ist. Tatsaechlich sind es aber mehr nicht fuer Zeichen nutzbare Kodierungen, naemlich der Bereich der Surrogates: https://en.wikipedia.org/wiki/UTF-16#U+ ... urrogates)debra hat geschrieben:03.10.2024 22:07:55Es scheint also doch Zeichen zu geben, die 3-Byte in UTF-8 haben und 4 in UTF-16. Eventuell ist da aber auch schlicht ein fehlerhaft codiertes Zeichen im Datensatz.
Diese lassen sich in UTF-8 in 3 Bytes kodieren, in UTF-16 brauchen aber nicht in 2 Bytes.
Statt ``fies'' wuerde ich sagen, dass das die Realitaet fuer den groessten Teil von digitalem Text auf dieser Welt ist.debra hat geschrieben:03.10.2024 22:07:55Klar das ist Natürlich ein bisschen fies, weil anteilig viel mehr Texte in englisch/Programmiersprachen... geschrieben sind als Straßennahmen.
Bei diesen Daten braucht UTF-16 deutlich mehr Speicher als UTF-8, naemlich 63% mehr.
Code: Alles auswählen
:-Q bc -ql
17957426*1 + 2616854*2 + 1142629*3 + 312*4
26620269
21716908*2 + 313*4
43435068
43435068/26620269
1.63165398516446246279
Use ed once in a while!
Re: Dateigröße <<< Speicherverbrauch
Ja bit-Operationen kosten meist gar nichts, weil eh irgend welches Memory zeug neben her läuft. Fallunterscheidungen sind extrem teuer, wenn sie falsch vorhergesagt werden.Meillo hat geschrieben:14.10.2024 17:12:06Vielleicht geht es dir auch vor allem um die Fallunterscheidungen, die oefters vorkommen als bei UTF-16.
Der Emoji Block ja. (Also so Sachen wie 🖍, ,🩷) Aber die klassischen Smilies: ♡,☺, ☹... nicht. Ich denke, dass letztere im Web immer noch deutlich häufiger sind.Meillo hat geschrieben:14.10.2024 17:12:06Meiner Recherche nach brauchen Emojis in beiden Encodings 4 Bytes
Kommt drauf an wie sehr man sich beschränkt: Punkt und Komma schon. Aber … „ “– ´ ¬ usw. nicht.Meillo hat geschrieben:14.10.2024 17:12:06und was ich unter Punktuation verstehe ist grossteils in US-ASCII enthalten
Das Programm hat auch noch obf geparsed und getestet ob das wirklich UTF-8 ist. Und hat sich im lauf der Zeit ein paar mal verändert.Meillo hat geschrieben:14.10.2024 17:12:06Danke fuer diese Auswertung. Zu meinem Testprogramm bin ich noch nicht gekommen. Aber du hast das ja schon optimal gemacht. Kannst du den Code des Programms hier posten?
Der relevante Teil:
Code: Alles auswählen
while ((c = fgetc(ifile)) != EOF){
if(!(c&0x80)){
onebyte++;
[...]
else
fputc(c,ofile);
} else if((c&0xe0)==0xc0) {
twobyte++;
fallowbytes(1,ifile,ofile,c);
} else if((c&0xf0)==0xe0) {
threebyte++;
fallowbytes(2,ifile,ofile,c);
} else if((c&0xf8)==0xf0) {
fourbyte++;
fallowbytes(3,ifile,ofile,c);
} else {
wrong++;
}
}
Code: Alles auswählen
void fallowbytes(int count, FILE* ifile, FILE* ofile,int c){
for(int i=0; i<count; i++)
fgetc(ifile);
}
Code: Alles auswählen
LANG=C.UTF-8
nc=$(cat file | iconv -t UTF-8 -f UTF-16 | wc -m | cut -d \ -f 1)
fb=$(($(wc -c file | cut -d \ -f 1)/2-$nc))
printf "%6d mal 2 Byte\n" $(($nc-$fb))
printf "%6d mal 4 Byte\n" $fb
Mit musst du halt ein
Code: Alles auswählen
tail -c +3 file > /tmp/tmpfile
mv /tmp/tmpfile file
Beachte, dass Wikipedia neben UTF-8 auch noch latex escapes und HTML References kennt. Dazu gibt es für vieles Wikimedia eigene Syntax wie WikiHiero für Hieroglyphen. Daneben gibt es je nach Wikipedias noch diverse Sprachspezifische Sachen: Sx wird in Espearnto zu Ŝ aber in der deutschen Wikipedia nicht. Daneben hatte die deutsche Wikipedia mal nen Bot, der ü und ê nach ü konvertiert. Aber kein Ŝ nach Ŝ... . Da die ganzen escapes alle ASCII sind und auch die Wiki Syntax nicht mit <>,{},[] und = spart, hast du gerne mal mehr [ als „ in nem deutschen Text. Ich wollte das zuerst auch nehmen. Hab dann aber aufgegeben.Ich wuerde es gerne mal auf deutsche, franzoesische und chinesische Wikipediaseiten anwenden.
Danke für die Info.Meillo hat geschrieben:14.10.2024 17:12:06Tatsaechlich sind es aber mehr nicht fuer Zeichen nutzbare Kodierungen, naemlich der Bereich der Surrogates: https://en.wikipedia.org/wiki/UTF-16#U+ ... urrogates)
Diese lassen sich in UTF-8 in 3 Bytes kodieren, in UTF-16 brauchen aber nicht in 2 Bytes.
Man bekommt halt nie eine repräsentative Form. Straßennahmen sind halt immer natürliche Sprachen. Oftmals längst ausgestorbene. Bäche und Dörfer hier haben fast immer Althochdeutsch/Alemannische Namen, die heute keiner mehr versteht. Die Straßennamen passen sich an. Als man uns Schwaben erklären wollte, dass man den Genitiv nicht mehr mit ingen bildet haben wir ihn abgeschafft. In Unseren Ortsnahmen lebt er weiter. Genau so wie die Aach bzw. weiter nördlich und östlich die Owe. Repräsentativ für Texte ist das nie gewesen. So viel haben die Germanen nicht niedergeschrieben. A w sind da garantiert massiv überrepräsentiert. ä und d sicher unterrepräsentiert. Umgekehrt ist das HTML, dass man im Web findet eben aber auch nicht repräsentativ für Texte. Denn schon Whatsapp packt nicht mehr alles in <extremlangerasciitag>. Und es gibt auch noch Bücher/PDFs. Alleine die 15 lisp Programme die geschrieben wurden dürften den Anteil an () merklich nach oben getrieben haben. .Meillo hat geschrieben:14.10.2024 17:12:06Statt ``fies'' wuerde ich sagen, dass das die Realitaet fuer den groessten Teil von digitalem Text auf dieser Welt ist.
Wie gesagt: Noch immer werden die aller meisten Texte im Internet nicht Websiten sein die Unmengen unnötigen ASCII einfügen und ü als ü encodieren.Meillo hat geschrieben:14.10.2024 17:12:06Ich vermute, dass dies bei fast allen Texten im Internet so sein wird, solange man nicht ausschliesslich in ostasiatischen Sprachraeumen unterwegs ist.
Chat GPT spuckt mir für Hallo Welt in HTML dasda aus:
Code: Alles auswählen
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hallo Welt</title>
</head>
<body>
<h1>Hallo Welt</h1>
<p>Willkommen auf meiner Webseite!</p>
</body>
</html>
Re: Dateigröße <<< Speicherverbrauch
Wir muessen Transferencodings von Zeichenencodings unterscheiden. Beim Transfer (in Quellcodeform) ist UTF-8 sicherlich am effizientesten weil sowas wie Markup-Tags und Ersatzkodierungen den ASCII-Anteil stark erhoeht. (Ausserdem ist die Byteorderunabhaengigkeit relevant.) Aber darum geht es hier ja nicht.debra hat geschrieben:16.10.2024 22:15:12Beachte, dass Wikipedia neben UTF-8 auch noch latex escapes und HTML References kennt. Dazu gibt es für vieles Wikimedia eigene Syntax wie WikiHiero für Hieroglyphen. Daneben gibt es je nach Wikipedias noch diverse Sprachspezifische Sachen: Sx wird in Espearnto zu Ŝ aber in der deutschen Wikipedia nicht. Daneben hatte die deutsche Wikipedia mal nen Bot, der ü und ê nach ü konvertiert. Aber kein Ŝ nach Ŝ... . Da die ganzen escapes alle ASCII sind und auch die Wiki Syntax nicht mit <>,{},[] und = spart, hast du gerne mal mehr [ als „ in nem deutschen Text.
Transfer- und Ersatzkodierungen sollen hier keine Rolle spielen, d.h. aus den sechs ASCII-Zeichen `ü' wird nach der Transferdekodierung ein Unicode-Zeichen U+00FC (was in UTF-8 und UTF-16 jeweils 2 Bytes benoetigt). Um dieses eine Zeichen in zwei Bytes geht es mir. Ich will also die Wikipedia-Seiten ``rendern'' und dann anschauen, nicht den HTML-Quellcode. ... falls ich jemals dazu komme.
Meine Vermutung ist weiterhin, dass dieses Ergebnis dann ebenfalls in UTF-8 weniger Speicherplatz braucht als in UTF-16. Fuer den europaeischen Sprachraum sowieso und vermutlich auch fuer den weltweiten Durchschnitt an allesn digitalen Textinhalten. (Ich vermute, dass es insgesamt mehr englischen Text in der digitalen Welt gibt als beispielsweise chinesischen.)
... wobei diese Diskussion letztlich muessig ist, weil sie nur auf Vermutungen basiert und nicht ueberprueft werden kann. Insgesamt haben wir das Thema inzwischen ja doch recht ausfuehrlich beackert ... und ich habe was ueber hardwarenahe vermutungsgetriebene Ausfuehrung gelernt. Auch wenn ich UTF-16 immer noch nicht mag, verstehe ich nun, was du daran sinnvoll findest.
Use ed once in a while!