XX:+UseCompressedStrings y Cordes compactes sont des choses différentes.
UseCompressedStrings
signifie que les chaînes de caractères qui sont uniquement ASCII peuvent être converties en byte[]
mais elle était désactivée par défaut. Dans jdk-9, cette optimisation est toujours activée, mais pas via le drapeau lui-même, mais par défaut.
Jusqu'à java-9, les chaînes de caractères sont stockées en interne sous la forme d'un fichier char[]
en encodage UTF-16. À partir de java-9, ils seront stockés en tant que byte[]
. Pourquoi ?
Parce que dans ISO_LATIN_1
chaque caractère peut être encodé dans un seul octet (8 bits) au lieu de ce qu'il était jusqu'à présent (16 bits, dont 8 ne sont jamais utilisés). Cela fonctionne uniquement para ISO_LATIN_1
mais c'est la majorité des cordes utilisées de toute façon.
C'est donc fait pour l'utilisation de l'espace.
Voici un petit exemple qui devrait rendre les choses plus claires :
class StringCharVsByte {
public static void main(String[] args) {
String first = "first";
String russianFirst = "";
char[] c1 = first.toCharArray();
char[] c2 = russianFirst.toCharArray();
for (char c : c1) {
System.out.println(c >>> 8);
}
for (char c : c2) {
System.out.println(c >>> 8);
}
}
}
Dans le premier cas, nous n'aurons que des zéros, ce qui signifie que les 8 bits les plus significatifs sont des zéros ; dans le second cas, il y aura une valeur non nulle, ce qui signifie qu'au moins un bit des 8 bits les plus significatifs est présent.
Cela signifie que si, en interne, nous stockons les chaînes de caractères sous la forme d'un tableau de caractères, il existe des chaînes de caractères qui gaspillent en fait la moitié de chaque caractère. Il s'avère qu'il existe de nombreuses applications qui gaspillent beaucoup d'espace à cause de cela.
Vous avez une chaîne de caractères composée de 10 caractères Latin1 ? Vous venez de perdre 80 bits, soit 10 octets. Pour atténuer cela, la compression des chaînes a été faite. Et maintenant, il n'y aura pas de perte d'espace pour ces chaînes.
En interne, cela signifie également des choses très intéressantes. Pour distinguer les chaînes qui sont LATIN1
y UTF-16
il y a un champ coder
:
/**
* The identifier of the encoding used to encode the bytes in
* {@code value}. The supported values in this implementation are
*
* LATIN1
* UTF16
*
* @implNote This field is trusted by the VM, and is a subject to
* constant folding if String instance is constant. Overwriting this
* field after construction will cause problems.
*/
private final byte coder;
Maintenant, sur la base de ce length
est calculée différemment :
public int length() {
return value.length >> coder();
}
Si notre chaîne est uniquement en Latin1, le codeur sera zéro, donc la longueur de la valeur (le tableau d'octets) est la taille des caractères. Pour les caractères non-Latin1, divisez par deux.
9 votes
Jamais entendu parler de comprimé les chaînes de caractères (en tant que chose), mais il existe un JEP sur les chaînes de caractères compactes : Cordes compactes .
6 votes
Eh bien, regardez-le maintenant :D Mais, c'est toujours aide pour indiquer où vous avez lu quelque chose.