문제는 (현재) 많은 데이터를 저장하는 것에 관한 것입니다.이 데이터는와 같은 기본 유형을 사용하여 나타낼 수 있습니다 int
. 여기에 대한 답변 중 일부는 내 의견으로는 매우 오도됩니다. 왜 그런지 보자.
런타임과 메모리 소비를 모두 측정하기 위해 Trove 에서 벤치 마크를 수정했습니다 . 또한 이 벤치 마크 에 PCJ 를 추가 했습니다.이 벤치 마크는 기본 유형에 대한 또 다른 콜렉션 라이브러리입니다 (저는 광범위하게 사용합니다). '공식적인'트 로브 벤치 마크는 IntIntMaps와 Java Collection의 비교를하지 않습니다 Map<Integer, Integer>
. 아마도 저장 Integers
과 저장 ints
은 기술적 인 관점에서 같지 않을 것입니다. 그러나 사용자는이 기술적 인 세부 사항에 신경 쓰지 않을 수 있으며 ints
효율적으로 표현할 수있는 데이터를 저장하려고합니다 .
먼저 코드의 관련 부분 :
new Operation() {
private long usedMem() {
System.gc();
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
// trove
public void ours() {
long mem = usedMem();
TIntIntHashMap ours = new TIntIntHashMap(SET_SIZE);
for ( int i = dataset.size(); i-- > 0; ) {
ours.put(i, i);
}
mem = usedMem() - mem;
System.err.println("trove " + mem + " bytes");
ours.clear();
}
public void pcj() {
long mem = usedMem();
IntKeyIntMap map = new IntKeyIntOpenHashMap(SET_SIZE);
for ( int i = dataset.size(); i-- > 0; ) {
map.put(i, i);
}
mem = usedMem() - mem;
System.err.println("pcj " + mem + " bytes");
map.clear();
}
// java collections
public void theirs() {
long mem = usedMem();
Map<Integer, Integer> map = new HashMap<Integer, Integer>(SET_SIZE);
for ( int i = dataset.size(); i-- > 0; ) {
map.put(i, i);
}
mem = usedMem() - mem;
System.err.println("java " + mem + " bytes");
map.clear();
}
나는 데이터가 원시적이라고 가정하고 ints
제정신처럼 보인다. 그러나 이것은 원시 복싱 프레임 워크에 필요하지 않은 자동 복싱으로 인해 java util에 대한 런타임 페널티를 의미합니다.
gc()
WinXP에서 jdk1.6.0_10 의 런타임 결과 ( 물론 호출 하지 않음 ) :
100000 넣기 작업 100000에는 작업이 포함됩니다
자바 컬렉션 1938 ms 203 ms
트로이 234ms 125ms
pcj 516ms 94ms
이것은 이미 과감하게 보일지 모르지만 이것이 그러한 프레임 워크를 사용하는 이유는 아닙니다.
그 이유는 메모리 성능입니다. 100000 int
개의 항목이 포함 된 맵의 결과 :
Java 콜렉션이 6644536과 7168840 바이트 사이에서 진동합니다.
트로이 1853296 바이트
pcj 1866112 바이트
Java Collections 는 프리미티브 콜렉션 프레임 워크에 비해 3 배 이상의 메모리 가 필요합니다 . 즉, 런타임 성능을 크게 저하시키는 디스크 IO에 의존하지 않고 메모리에 3 배 많은 데이터를 유지할 수 있습니다. 그리고 이것은 중요합니다. 그 이유를 알아 보려면 높은 확장 성 을 읽으십시오 .
내 경험에 따르면 높은 메모리 소비는 Java의 가장 큰 성능 문제이며 물론 런타임 성능도 저하됩니다. 프리미티브 콜렉션 프레임 워크가 실제로 도움이 될 수 있습니다.
따라서 : 아니오, java.util은 답이 아닙니다. Java 컬렉션에 "기능 추가"는 효율성을 요구할 때 중요하지 않습니다. 또한 최신 JDK 컬렉션은 "특수한 Trove 컬렉션보다 성능이 우수 하지 않습니다 ".
면책 조항 : 여기서 벤치 마크는 완전하지도 않고 완벽하지도 않습니다. 그것은 많은 프로젝트에서 경험했던 요점을 집으로 몰아 넣는 것입니다. 기본 컬렉션은 많은 양의 데이터로 작업하는 경우 비린내 API를 견딜 수있을 정도로 유용 합니다.