JVM 시리즈 의 String.intern 성능 분석
5288 단어 String.intern
그럼 String.intern 의 성능 은 어 떻 습 니까?같이 보 자.
String.intern 과 G1 문자열 의 차이 점 제거
앞서 언급 했 듯 이 String.intern 방법 은 문자열 상수 탱크 의 문자열 대상 에 대한 인용 을 되 돌려 줍 니 다.
G1 쓰레기 수 거 기의 문자열 을 무 게 를 줄 이 는 기능 은 String.intern 과 조금 다 릅 니 다.G1 은 두 문자열 의 아래쪽 을 같은 byte[]배열 로 가리 키 는 것 입 니 다.
증거 로 삼 을 그림 이 있다.
위의 그림 에서 String 1 과 String 2 는 같은 byte[]배열 을 가리 키 고 있 습 니 다.
String.intern 의 성능
인터넷 방법의 정 의 를 봅 시다.
public native String intern();
보시 다시 피 이것 은 native 의 방법 입 니 다.native 밑바닥 은 틀림없이 C++가 실 현 된 것 이다.그럼 네 이 티 브 방법 이 자바 방법 보다 빠 를 까요?
사실 native 방법 은 이렇게 몇 가지 시간 이 걸 립 니 다.
아니면 JMH 도구 로 성능 분석 을 할 까요?저 희 는 String.intern,HashMap,Concurrent HashMap 을 사용 하여 비교 분석 을 하고 각각 1 회,100 회,10000 회,1000000 회 를 호출 합 니 다.
코드 는 다음 과 같 습 니 다:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Fork(value = 1, jvmArgsPrepend = "-XX:+PrintStringTableStatistics")
@Warmup(iterations = 5)
@Measurement(iterations = 5)
public class StringInternBenchMark {
@Param({"1", "100", "10000", "1000000"})
private int size;
private StringInterner str;
private ConcurrentHashMapInterner chm;
private HashMapInterner hm;
@Setup
public void setup() {
str = new StringInterner();
chm = new ConcurrentHashMapInterner();
hm = new HashMapInterner();
}
public static class StringInterner {
public String intern(String s) {
return s.intern();
}
}
@Benchmark
public void useIntern(Blackhole bh) {
for (int c = 0; c < size; c++) {
bh.consume(str.intern("doit" + c));
}
}
public static class ConcurrentHashMapInterner {
private final Map<String, String> map;
public ConcurrentHashMapInterner() {
map = new ConcurrentHashMap<>();
}
public String intern(String s) {
String exist = map.putIfAbsent(s, s);
return (exist == null) ? s : exist;
}
}
@Benchmark
public void useCurrentHashMap(Blackhole bh) {
for (int c = 0; c < size; c++) {
bh.consume(chm.intern("doit" + c));
}
}
public static class HashMapInterner {
private final Map<String, String> map;
public HashMapInterner() {
map = new HashMap<>();
}
public String intern(String s) {
String exist = map.putIfAbsent(s, s);
return (exist == null) ? s : exist;
}
}
@Benchmark
public void useHashMap(Blackhole bh) {
for (int c = 0; c < size; c++) {
bh.consume(hm.intern("doit" + c));
}
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(StringInternBenchMark.class.getSimpleName())
.build();
new Runner(opt).run();
}
}
출력 결과:Benchmark (size) Mode Cnt Score Error Units
StringInternBenchMark.useCurrentHashMap 1 avgt 5 34.259 ± 7.191 ns/op
StringInternBenchMark.useCurrentHashMap 100 avgt 5 3623.834 ± 499.806 ns/op
StringInternBenchMark.useCurrentHashMap 10000 avgt 5 421010.654 ± 53760.218 ns/op
StringInternBenchMark.useCurrentHashMap 1000000 avgt 5 88403817.753 ± 12719402.380 ns/op
StringInternBenchMark.useHashMap 1 avgt 5 36.927 ± 6.751 ns/op
StringInternBenchMark.useHashMap 100 avgt 5 3329.498 ± 595.923 ns/op
StringInternBenchMark.useHashMap 10000 avgt 5 417959.200 ± 62853.828 ns/op
StringInternBenchMark.useHashMap 1000000 avgt 5 79347127.709 ± 9378196.176 ns/op
StringInternBenchMark.useIntern 1 avgt 5 161.598 ± 9.128 ns/op
StringInternBenchMark.useIntern 100 avgt 5 17211.037 ± 188.929 ns/op
StringInternBenchMark.useIntern 10000 avgt 5 1934203.794 ± 272954.183 ns/op
StringInternBenchMark.useIntern 1000000 avgt 5 418729928.200 ± 86876278.365 ns/op
결과적으로 우 리 는 인터넷 이 다른 두 개 보다 느리다 는 것 을 알 수 있다.
그래서 네 이 티 브 방법 이 빠 르 지 는 않 아 요.intern 의 용 도 는 속도 가 아니 라 힙 의 메모리 사용 을 절약 하 는 데 있다.
JVM 시리즈 의 String.intern 의 성능 분석 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.String.intern 의 성능 에 관 한 더 많은 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!