Ich habe eine Javascript-Zeichenfolge, die ungefähr 500 KB groß ist, wenn sie vom Server in UTF-8 gesendet wird. Wie kann ich die Größe in JavaScript bestimmen?
Ich weiß, dass JavaScript UCS-2 verwendet, das bedeutet also 2 Bytes pro Zeichen. Hängt es jedoch von der JavaScript-Implementierung ab? Oder auf der Seite Kodierung oder vielleicht Inhaltstyp?
javascript
string
size
byte
Paul Biggar
quelle
quelle
Antworten:
String
Die Werte sind nicht implementierungsabhängig. Gemäß der ECMA-262 3rd Edition-Spezifikation repräsentiert jedes Zeichen eine einzelne 16-Bit-Einheit des UTF-16-Textes :quelle
Diese Funktion gibt die Bytegröße aller UTF-8-Zeichenfolgen zurück, die Sie an sie übergeben.
Quelle
JavaScript-Engines können UCS-2 oder UTF-16 intern verwenden. Die meisten mir bekannten Engines verwenden UTF-16, aber was auch immer sie gewählt haben, es ist nur ein Implementierungsdetail, das die Eigenschaften der Sprache nicht beeinflusst.
Die ECMAScript / JavaScript-Sprache selbst macht jedoch Zeichen gemäß UCS-2 und nicht UTF-16 verfügbar.
Quelle
quelle
.split(/%(?:u[0-9A-F]{2})?[0-9A-F]{2}|./)
stattdessen. Ihr Snippet schlägt für Zeichenfolgen fehl, die in "% uXXXX" codiert sind.Wenn Sie node.js verwenden, gibt es eine einfachere Lösung mit Puffern :
Dafür gibt es eine npm lib: https://www.npmjs.org/package/utf8-binary-cutter (von Ihnen treu)
quelle
Sie können den Blob verwenden , um die Zeichenfolgengröße in Bytes abzurufen.
Beispiele:
quelle
Buffer.from('😂').length
Versuchen Sie diese Kombination mit der Funktion unescape js:
const byteAmount = unescape(encodeURIComponent(yourString)).length
Beispiel für einen vollständigen Codierungsprozess:
quelle
unescape
JavaScript-Funktion ist veraltet und sollte nicht zum Dekodieren von URI (Uniform Resource Identifiers) verwendet werden. Quelleunescape
wird nicht verwendet, um URIs zu dekodieren . Es wird verwendet, um%xx
Sequenzen in einzelne Zeichen umzuwandeln . WennencodeURIComponent
eine Zeichenfolge als UTF-8 codiert wird, die Codeeinheiten entweder als entsprechendes ASCII-Zeichen oder als%xx
Sequenz darstellt, führt der Aufrufunescape(encodeURIComponent(...))
zu einer binären Zeichenfolge, die die UTF-8-Darstellung der ursprünglichen Zeichenfolge enthält. Beim.length
korrekten Aufrufen wird die Größe der als UTF-8 codierten Zeichenfolge in Byte angegeben.un
)escape
ist seit 1999 veraltet, aber es ist immer noch in jedem Browser verfügbar ... - Das heißt, es gibt gute Gründe, es zu verwerfen. Grundsätzlich gibt es keine Möglichkeit, sie korrekt zu verwenden (außer UT- / En- / Decodierung von UTF8 in Kombination miten
- /decodeURI
(Component
) - oder zumindest kenne ich keine andere nützliche Anwendung für (un
)escape
). Und heute gibt es bessere Alternativen zum Codieren / Decodieren von UTF8 (TextEncoder
usw.)Beachten Sie, dass Sie Folgendes verwenden können, wenn Sie auf node.js abzielen
Buffer.from(string).length
:quelle
UTF-8 codiert Zeichen mit 1 bis 4 Bytes pro Codepunkt. Wie CMS in der akzeptierten Antwort hervorhob, speichert JavaScript jedes Zeichen intern mit 16 Bit (2 Byte).
Wenn Sie jedes Zeichen in der Zeichenfolge über eine Schleife analysieren und die Anzahl der pro Codepunkt verwendeten Bytes zählen und dann die Gesamtzahl mit 2 multiplizieren, sollte die Speichernutzung von JavaScript in Bytes für diese UTF-8-codierte Zeichenfolge angegeben werden. Vielleicht so etwas:
Beispiele:
quelle
Dies sind 3 Möglichkeiten, die ich benutze:
TextEncoder ()
(new TextEncoder().encode("myString")).length)
Klecks
new Blob(["myString"]).size)
Puffer
Buffer.byteLength("myString", 'utf8'))
quelle
Die Antwort von Lauri Oherd funktioniert gut für die meisten in freier Wildbahn gesehenen Zeichenfolgen, schlägt jedoch fehl, wenn die Zeichenfolge einzelne Zeichen im Bereich der Ersatzpaare 0xD800 bis 0xDFFF enthält. Z.B
Diese längere Funktion sollte alle Zeichenfolgen verarbeiten:
Z.B
Die Größe für Zeichenfolgen mit Ersatzpaaren wird korrekt berechnet:
Die Ergebnisse können mit der integrierten Funktion von Node verglichen werden
Buffer.byteLength
:quelle
Die Größe einer JavaScript-Zeichenfolge beträgt
Pre-ES6
Immer 2 Bytes pro Zeichen. UTF-16 ist nicht zulässig, da in der Spezifikation angegeben ist, dass "Werte vorzeichenlose 16-Bit-Ganzzahlen sein müssen". Da UTF-16-Zeichenfolgen 3- oder 4-Byte-Zeichen verwenden können, würde dies die 2-Byte-Anforderung verletzen. Entscheidend ist, dass UTF-16 zwar nicht vollständig unterstützt werden kann, der Standard jedoch vorschreibt, dass die beiden verwendeten Bytezeichen gültige UTF-16-Zeichen sind. Mit anderen Worten, JavaScript-Zeichenfolgen vor ES6 unterstützen eine Teilmenge von UTF-16-Zeichen.
ES6 und höher
2 Bytes pro Zeichen oder 5 oder mehr Bytes pro Zeichen. Die zusätzlichen Größen kommen ins Spiel, da ES6 (ECMAScript 6) die Unterstützung für Unicode-Codepunkt- Escapezeichen hinzufügt . Die Verwendung eines Unicode-Escape sieht folgendermaßen aus: \ u {1D306}
Praktische Hinweise
Dies bezieht sich nicht auf die interne Implementierung eines bestimmten Motors. Beispielsweise verwenden einige Engines Datenstrukturen und Bibliotheken mit vollständiger UTF-16-Unterstützung, aber was sie extern bereitstellen, muss nicht vollständige UTF-16-Unterstützung sein. Ein Motor kann auch externe UTF-16-Unterstützung bieten, ist jedoch nicht dazu verpflichtet.
Für ES6 werden praktisch keine Zeichen länger als 5 Byte sein (2 Byte für den Escape-Punkt + 3 Byte für den Unicode-Codepunkt), da die neueste Version von Unicode nur 136.755 mögliche Zeichen enthält, was problemlos in 3 Byte passt. Dies ist jedoch technisch nicht durch den Standard beschränkt, so dass im Prinzip ein einzelnes Zeichen beispielsweise 4 Bytes für den Codepunkt und 6 Bytes insgesamt verwenden könnte.
Die meisten Codebeispiele hier zur Berechnung der Bytegröße scheinen ES6-Unicode-Codepunkt-Escapezeichen nicht zu berücksichtigen, sodass die Ergebnisse in einigen Fällen falsch sein können.
quelle
Buffer.from('test').length
undBuffer.byteLength('test')
entspricht 4 (im Knoten) undnew Blob(['test']).size
entspricht auch 4?'\u{1F600}'.length===2
,'\u{1F600}'==='\uD83D\uDE00'
,'\u{1F600}'==='😀'
)Ich arbeite mit einer eingebetteten Version der V8-Engine. Ich habe eine einzelne Zeichenfolge getestet. Drücken Sie jeden Schritt 1000 Zeichen. UTF-8.
Erster Test mit Einzelbyte (8 Bit, ANSI) Zeichen "A" (hex: 41). Zweiter Test mit zwei Byte (16 Bit) "Ω" (hex: CE A9) und der dritte Test mit drei Byte (24 Bit) "☺" (hex: E2 98 BA).
In allen drei Fällen druckt das Gerät mit 888 000 Zeichen und ca. 26 348 kb im RAM.
Ergebnis: Die Zeichen werden nicht dynamisch gespeichert. Und nicht nur mit 16bit. - Ok, vielleicht nur für meinen Fall (Embedded 128 MB RAM-Gerät, V8 Engine C ++ / QT) - Die Zeichencodierung hat nichts mit der RAM-Größe der Javascript-Engine zu tun. Beispielsweise ist die Codierung von UUR usw. nur für die Übertragung und Speicherung von Daten auf hoher Ebene nützlich.
Eingebettet oder nicht, Tatsache ist, dass die Zeichen nicht nur in 16 Bit gespeichert sind. Leider habe ich keine 100% ige Antwort, was Javascript auf niedriger Ebene macht. Übrigens. Ich habe das gleiche (erster Test oben) mit einem Array von Zeichen "A" getestet. Schob 1000 Gegenstände pro Schritt. (Genau der gleiche Test. Nur String in Array ersetzt) Und das System bringt nach 10 416 KB mit einer Array-Länge von 1 337 000 nicht mehr genügend Speicher (gewünscht). Die Javascript-Engine ist also nicht einfach eingeschränkt. Es ist etwas komplexer.
quelle
Ein einzelnes Element in einer JavaScript-Zeichenfolge wird als einzelne UTF-16-Codeeinheit betrachtet. Das heißt, Zeichenfolgenzeichen werden in 16 Bit (1 Codeeinheit) gespeichert, und 16 Bit entspricht 2 Bytes (8 Bit = 1 Byte).
Die
charCodeAt()
Methode kann verwendet werden, um eine Ganzzahl zwischen 0 und 65535 zurückzugeben, die die UTF-16-Codeeinheit am angegebenen Index darstellt.Mit
codePointAt()
kann der gesamte Codepunktwert für Unicode-Zeichen zurückgegeben werden, z. B. UTF-32.Wenn ein UTF-16-Zeichen nicht in einer einzelnen 16-Bit-Codeeinheit dargestellt werden kann, hat es ein Ersatzpaar und verwendet daher zwei Codeeinheiten (2 x 16-Bit = 4 Byte).
Unter Unicode-Codierungen finden Sie verschiedene Codierungen und ihre Codebereiche.
quelle
Sie können dies versuchen:
Es hat bei mir funktioniert.
quelle