Java 9에서 압축 문자열과 압축 문자열의 차이점
의 장점은 무엇입니까 컴팩트 문자열 JDK9에서 압축 된 문자열 이상은?
압축 된 문자열 (Java 6)과 압축 된 문자열 (Java 9)은 모두 동일한 동기 (문자열은 사실상 Latin-1이므로 공간의 절반이 낭비 됨)와 목표 (문자열을 작게 만들기)는 동일하지만 구현 방식이 많이 다릅니다.
압축 된 문자열
에서 의 인터뷰 (자바 (9) 기능을 구현 담당 한) 알렉세이 Shipilëv이 압축 문자열에 대해 말을했다 :
구별 동안 : UseCompressedStrings 기능은 보수적이었다
char[]
및byte[]
케이스, 그리고 압축하려고char[]
로byte[]
의String
건설이 대부분 완료String
에 대한 작업을char[]
압축을 풀 필요가있는,String.
따라서 때문에 (대부분의 문자열이 압축되어 워크로드의 특별한 유형의 혜택을, 압축은 낭비되지 않으며 제한된 양의 알려진String
작업 만 수행됩니다 (따라서 포장을 풀지 않아도 됨). 많은 워크로드에서 활성화-XX:+UseCompressedStrings
는 비관적이었습니다.[...] UseCompressedStrings 구현은 기본적으로 VM 옵션이 제공되면로드 된
String
에서 완전히 별개의 구현 을 유지하는 선택적 기능alt-rt.jar
이었습니다. 옵션 기능은 시도 할 옵션 조합의 수를 두 배로 늘리기 때문에 테스트하기가 더 어렵습니다.
콤팩트 스트링
반면에 Java 9에서는 압축 문자열이 JDK 소스에 완전히 통합됩니다. String
되어 항상 바탕으로 byte[]
그들은 라틴어-1과 달리이 경우 문자는 한 바이트를 사용하는 경우. 대부분의 작업은 어떤 경우인지 확인합니다. 예 charAt
:
public char charAt(int index) {
if (isLatin1()) {
return StringLatin1.charAt(value, index);
} else {
return StringUTF16.charAt(value, index);
}
}
압축 문자열은 기본적으로 활성화되며 부분적으로 비활성화 될 수 있습니다. "부분적으로"여전히 a에 의해 지원되고 s를 byte[]
반환 하는 작업 char
은 여전히 두 개의 개별 바이트에서 이들을 모아야합니다 (내 재성 때문에 이것이 성능에 영향을 미치는지 여부를 말하기는 어렵습니다). ).
더
콤팩트 한 스트링에 대한 더 많은 배경에 관심이 있다면 위에서 링크 한 인터뷰 를 읽 거나 동일한 Aleksey Shipilëv (새로운 스트링 연결에 대해서도 설명 함)의 훌륭한 강연을 시청하는 것이 좋습니다 .
XX : + UseCompressedStrings 와 Compact Strings 는 서로 다릅니다.
UseCompressedStrings
즉, ASCII 인 문자열은로만 변환 할 수 byte[]
있지만 기본적으로 꺼져 있습니다. jdk-9에서이 최적화는 항상 켜져 있지만 플래그 자체를 통하지 않고 내장되어 있습니다.
java-9 문자열이 내부적으로 char[]
UTF-16 인코딩 으로 저장 될 때까지 . java-9 이상에서는 byte[]
. 왜?
ISO_LATIN_1
각 문자에서 단일 바이트 (8 비트)로 인코딩 할 수 있기 때문에 지금까지 사용했던 것과 비교하면됩니다 (16 비트, 사용하지 않은 경우 각각 8 비트). 이 작품 만을 위해 ISO_LATIN_1
,하지만 문자열의 대부분이 어쨌든 사용됩니다.
그래서 그것은 공간 사용을 위해 수행됩니다.
다음은 더 명확하게해야하는 작은 예입니다.
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);
}
}
}
첫 번째 경우 우리는 0 만 얻을 것입니다. 즉, 최상위 8 비트는 0입니다. 두 번째 경우에는 0이 아닌 값이있을 것입니다. 즉, 최상위 8에서 적어도 하나의 비트가 존재 함을 의미합니다.
즉, 내부적으로 문자열을 문자 배열로 저장하면 실제로 각 문자의 절반을 낭비하는 문자열 리터럴이 있습니다. 이 때문에 실제로 많은 공간을 낭비하는 여러 응용 프로그램이 있습니다.
10 개의 Latin1 문자로 만든 문자열이 있습니까? 방금 80 비트 또는 10 바이트를 잃었습니다. 이 문자열 압축을 완화하기 위해 만들어졌습니다. 이제 이러한 문자열에 대한 공간 손실이 없습니다.
내부적으로 이것은 또한 매우 좋은 것을 의미합니다. 있는 문자열 LATIN1
과 UTF-16
필드가있는 것을 구별하려면 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;
Now based on this length
is computed differently:
public int length() {
return value.length >> coder();
}
If our String is Latin1 only, coder is going to be zero, so length of value (the byte array) is the size of chars. For non-Latin1 divide by two.
Compact Strings will have best of both worlds.
As can be seen in the definition provided in OpenJDK documentation:
The new String class will store characters encoded either as ISO-8859-1/Latin-1 (one byte per character), or as UTF-16 (two bytes per character), based upon the contents of the string. The encoding flag will indicate which encoding is used.
As mentioned by @Eugene, most of the strings are encoded in Latin-1 format and require one byte per character and hence do not require the whole 2-byte space provide in current String class implementation.
The new String class implementation will shift from UTF-16 char array
to a byte array
plus an encoding-flag field. The additional encoding field will show whether the characters are stored using UTF-16 or Latin-1 format.
This also concludes that we will also be able to store strings in UTF-16 format if required. And this also becomes the main point of difference between the Compressed String of Java 6 and Compact String of Java 9 as in Compressed String only byte[] array was used for storage which was then representated as pure ASCII.
Compressed Strings (-XX:+UseCompressedStrings)
This was a optional feature introduced in Java 6 Update 21 to improve SPECjbb performance by encoding only US-ASCII String on a byte per character.
This feature can be enabled by an -XX
flag (-XX:+UseCompressedStrings
). When it is enabled, String.value
was changed to an Object reference and would point either to a byte[]
, for strings containing only 7-bit US-ASCII characters, or else a char[]
.
Later it was removed in Java 7 because of high maintenance and hard to test.
Compact String
This is a new feature introduced in Java 9 to build a memory efficient String.
Before Java 9, the String class stored characters in a char array, using two bytes for each character but from Java 9 the new String class will store characters in byte[]
(one byte per character) or char[]
(two bytes per character), based upon the contents of the string, plus an encoding-flag field. If String characters are of type Latin-1
then byte[]
will be used else if characters are of type UTF-16
then char[]
will be used. The encoding flag will indicate which encoding is used.
'developer tip' 카테고리의 다른 글
Python ElementTree를 문자열로 변환 (0) | 2020.11.18 |
---|---|
활동과 조각의 차이점은 무엇입니까? (0) | 2020.11.18 |
Python 'for'루프를위한 더 나은 방법 (0) | 2020.11.18 |
std :: queue 반복 (0) | 2020.11.18 |
Ruby on Rails-여러 모델에 대한 JSON 렌더링 (0) | 2020.11.18 |