참고 : 성능 문제에 대해서는 이 아니라이 아닙니다. 나는 설명/이해할 수없는 성과의 차이 만 관찰합니다.HashMap 성능 Java 9 Java 8보다 25 % 적게?
일부 새롭게 개발 된 코드를 벤치마킹하면서 Java 9를 타겟으로하면서 이상한 것을 발견했습니다. HashMap
(매우 간단한) 벤치 마크 (5 키 포함)는 Java 9가 Java 8보다 훨씬 느리다는 것을 나타냅니다. 설명 할 수 있습니까? 아니면 내 (벤치 마크) 코드가 잘못 되었습니까?
코드 :
@Fork(
jvmArgsAppend = {"-Xmx512M", "-disablesystemassertions"}
)
public class JsonBenchmark {
@State(Scope.Thread)
public static class Data {
final static Locale RUSSIAN = new Locale("ru");
final static Locale DUTCH = new Locale("nl");
final Map<Locale, String> hashmap = new HashMap<>();
public Data() {
hashmap.put(Locale.ENGLISH, "Flat flashing adjustable for flat angled roof with swivel");
hashmap.put(Locale.FRENCH, "Solin pour toit plat inclinée");
hashmap.put(Locale.GERMAN, "Flachdachkragen Flach Schrägdach");
hashmap.put(DUTCH, "Plakplaat vlak/hellend dak inclusief glijschaal");
hashmap.put(RUSSIAN, "Проход через плоскую кровлю регулир. для накл. кровли");
}
}
@Benchmark
public int bmHashMap(JsonBenchmark.Data data) {
final Map<Locale, String> m = data.hashmap;
int sum = 0;
sum += m.get(Data.RUSSIAN).length();
sum += m.get(Locale.FRENCH).length();
sum += m.get(Data.DUTCH).length();
sum += m.get(Locale.ENGLISH).length();
sum += m.get(Locale.GERMAN).length();
return sum;
}
}
결과 :
- 자바 8_151 : JsonBenchmark.bmHashMap 40 47948546.439 ± 560763.711 작전을 thrpt/s의
- 자바 9_181는 : JsonBenchmark.bmHashMap 40 34962904.479 ± 276045.691 작전을 thrpt/s (-/- 27 %!)
업데이트
답변과 훌륭한 의견을 보내 주셔서 감사합니다.
@Holger의 제안. 저의 첫 반응은 설명 일 것입니다. 그러나, 만약 내가 벤치마킹
String#length()
기능, 성능에 큰 차이가 없습니다. 그리고 (@Eugene에서 제안한 것처럼)HashMap#get()
메서드를 벤치 마크 할 때 여전히 약 10-12 %의 차이가 있습니다.@Eugene의 제안. 매개 변수를 변경 (더 많은 워밍업 반복, 더 많은 메모리)했지만 결과를 재현 할 수 없습니다. 그러나 나는 4G로 힙을 늘렸다. 그러나 이것은 차이를 설명 할 수는 없지 않습니까?
@Alan Bateman의 제안. 예, 성능이 향상됩니다! 그러나 여전히 약 20 %의 차이가 있습니다.
나는 당신이 부정 상관 없어 전부. 그러나 가능한 한 jmh의 초심자인데 두 버전 모두에서 .length의 복잡성 비교를 말할 수 있습니까? 그 대답과 통계를 이해하는 동안 그것을 보는 것이 좋을 것입니다. 내가 뭔가를 알아낼 수 있는지 알아보기 위해 [여기] (http://cr.openjdk.java.net/~shade/8085796/notes.txt)를 찾았지만 대부분은 내 머리 위로 갔다. – nullpointer
좋은 답변입니다. 또 하나 언급해야 할 것은 -XX : -CompactStrings를 사용하면 압축 문자열을 사용하지 않을 때와 다른 성능을 볼 수 있습니다. –
@nullpointer : 이전 구현은'array.length'와 같았습니다. 새로운 구현은'arrays.length >> coder'와 같습니다. wheres coder는 문자열에 따라 0 또는 1입니다. 실제 응용 프로그램에 미치는 영향은'length()'가 실제로 얼마나 자주 호출되는지와 latin1 문자열과 다른 문자열 사이의 비율에 달려 있습니다. 일부 다른 문자열 연산은 latin1 문자열 (더 적은 바이트가 돌아 다니는)에 대해 더 빠를 수도 있습니다. 이는 더 많은 것을 보완 할 수 있습니다. – Holger