가장 효율적인 Java Collections 라이브러리는 무엇입니까?
가장 효율적인 Java Collections 라이브러리는 무엇입니까?
몇 년 전, 저는 Java를 많이 사용했는데, 당시 trove가 Java Collections의 가장 효율적인 구현이라는 인상을 받았습니다.하지만 내가 "가장 유용한 무료 자바 라이브러리?"라는 질문에 대한 답을 읽었을 때.나는 괴물이 거의 언급되지 않는다는 것을 알아차렸다.그렇다면 현재 가장 적합한 Java Collections 라이브러리는 무엇일까요?
업데이트: 명확하게 하기 위해 해시 테이블 등에 수백만 개의 엔트리를 저장해야 할 때 사용하는 라이브러리를 알고 싶습니다(실행시 및 메모리 용량이 작아야 합니다).
질문은 다음과 같은 원시 유형을 사용하여 나타낼 수 있는 많은 데이터를 저장하는 것입니다.int
, 지도에 있습니다.여기 있는 몇 가지 답변은 제 생각에 매우 오해를 불러일으키고 있습니다.왜 그런지 보자.
실행 시 및 메모리 소비량을 측정하기 위해 벤치마크를 trove에서 수정했습니다.또, 이 벤치마크에 PCJ를 추가했습니다.이것은 다른 원시 타입의 컬렉션 라이브러리입니다(그것을 폭넓게 사용하고 있습니다).공식 trove 벤치마크에서는 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()
콜(물론), jdk1.6.0_10:
100000 put 연산 100000에 연산 포함java 컬렉션 1938 ms 203 mstrove 234 ms 125 mspcj 516 ms 94 ms
이미 극단적으로 보일 수 있지만, 이것이 이러한 프레임워크를 사용할 이유는 아닙니다.
그 이유는 메모리 성능입니다. 100000을 int
★★★★★★★★★★★★★★★★★★:
Java 컬렉션은 6644536 ~7168840 바이트 사이에서 진동합니다.trove 1853296 바이트pcj 1866112 바이트
Java Collections는 원시 컬렉션 프레임워크에 비해 3배 이상의 메모리가 필요합니다.즉, Disk IO에 의존하지 않고 메모리에 3배 더 많은 데이터를 저장할 수 있으므로 런타임 성능이 크게 저하됩니다.그리고 이것은 중요하다.높은 확장성을 읽고 이유를 알아보십시오.
제 경험상 메모리 소비량이 높은 것은 Java의 가장 큰 성능 문제이며, 이는 물론 실행 시 성능 저하로 이어집니다.원시적인 컬렉션 프레임워크는 여기에 큰 도움이 됩니다.
그래서: 아니요, java.util은 답이 아닙니다.또한 Java 컬렉션에 "기능 추가"를 하는 것이 효율성에 대한 질문의 요점이 아닙니다.또한 최신 JDK 컬렉션은 "특화된 Trove 컬렉션도 능가하는 성능"을 발휘하지 않습니다.
면책사항:여기서의 벤치마크는 완전하지 않고 완벽하지도 않습니다.그것은 내가 많은 프로젝트에서 경험해 온 요점을 이해시키기 위한 것이다.원시 컬렉션은 많은 데이터를 사용하는 경우 API가 의심스러운 것을 허용할 수 있을 정도로 유용합니다.
검사 결과 Trove는 단순한 원시형 컬렉션 라이브러리인 것 같습니다.JDK의 일반 컬렉션보다 많은 기능을 추가하는 것은 아닙니다.
개인적으로(그리고 나는 편견이 있다) 나는 구아바(구글 자바 컬렉션 프로젝트 포함)를 사랑한다.적어도 합리적으로 효율적인 방법으로 다양한 작업(수집 포함)을 훨씬 쉽게 할 수 있습니다.수집 조작이 코드에 병목 현상을 일으키는 경우는 거의 없기 때문에 (내 경험상) 이것은 더 효율적일 수 있지만 코드를 읽을 수 있는 것처럼 만들지 않는 수집 API보다 "더 좋다"고 할 수 있습니다.
Trove와 Guava의 중복이 거의 없는 것을 고려하면, 당신은 컬렉션 라이브러리에서 실제로 무엇을 찾고 있는지 명확히 할 수 있을 것이다.
나는 이것이 오래된 게시물이고 여기에 많은 답변들이 있다는 것을 안다.그러나 위의 답변은 도서관을 제안하는 측면에서 피상적이고 지나치게 단순하다.여기에 제시된 다양한 벤치마크에서 뛰어난 성능을 발휘하는 라이브러리는 없습니다.제가 도출한 결론은 성능과 메모리에 관심을 가지고 있으며, 특히 원시 유형을 다루는 경우 jdk 이외의 대안을 검토할 가치가 있다는 것입니다.
벤치마크 메카니즘과 대상 라이브러리의 관점에서 보다 건전한 분석을 실시합니다.이것은 mahout dev 목록의 스레드입니다.
대상 라이브러리는 다음과 같습니다.
- HPPC
- 트로브
- Fast Util
- Mahout (콜트)
- Java 컬렉션
2015년 6월 업데이트: 안타깝게도 원래의 벤치마크는 더 이상 사용할 수 없으며 약간 구식입니다.다음은 다른 사용자가 수행한 상당히 최근의(2015년 1월) 벤치마크입니다.원래 링크만큼 포괄적이지도 않고 인터랙티브 탐색 도구도 없습니다.
다른 논객들이 알아차렸듯이, "효율적"이라는 정의는 넓은 망을 드리우고 있다.그러나 Javolution 라이브러리는 아직 아무도 언급하지 않았다.
주요 내용:
- Javolution 클래스는 빠르고 매우 빠릅니다(예를 들어 표준 StringBuffer/StringBuilder의 경우 O[n]가 아닌 O[Log (n)]로 텍스트 삽입/삭제).
- 모든 Javolution 클래스는 하드 실시간 호환되며 매우 결정론적 동작(마이크로초 범위)을 가집니다.또한(표준 라이브러리와 달리) Javolution은 RTSJ에 안전합니다(Java Real-Time 확장과 함께 사용할 경우 메모리 충돌이나 메모리 누수가 없습니다).
- Javolution의 실시간 컬렉션 클래스(맵, 목록, 테이블 및 세트)는 대부분의 표준 컬렉션 클래스 대신 사용할 수 있으며 추가 기능을 제공합니다.
- Javolution 컬렉션은 병렬 알고리즘을 보다 쉽게 구현할 수 있도록 동시성을 보장합니다.
Javolution 배포판에는 벤치마크 제품군이 포함되어 있으므로 다른 라이브러리/빌트인 컬렉션과 비교해서 얼마나 비교되는지 확인할 수 있습니다.
일부 회수libs는 다음을 고려한다.
- java.util의 Java 컬렉션
- 트로브
- Google 컬렉션 라이브러리
- Apache Commons 컬렉션
- Cliff Click의 대규모 lib
- Doug Lea의 컬렉션 lib - 더 이상 지원되지 않으며 대부분 JDK로 재구축됨
우선 JDK 컬렉션 라이브러리에 손을 뻗습니다.이 문서에는 사용자가 수행해야 하는 대부분의 일반적인 작업이 포함되어 있으며, 이미 사용할 수 있습니다.
Google Collections는 JDK 이외의 최고의 고품질 라이브러리일 것입니다.많이 쓰이고 잘 지원되고 있습니다.
Apache Commons Collections는 더 오래되었고 "너무 많은 요리사" 문제로 다소 어려움을 겪고 있지만 유용한 물건들도 많이 있습니다.
Trove는 원시 키/값과 같은 경우에 대해 매우 특별한 컬렉션을 가지고 있습니다.오늘날에는 최신 JDK, Java 5+ 컬렉션 및 동시 사용 사례에서 JDK 컬렉션이 전문 Trove 컬렉션보다 성능이 우수하다는 것을 알 수 있습니다.
동시 사용 사례가 매우 높은 경우 잠금 기능이 없는 구현으로 적절한 사용 사례가 있으면 Concurrent HashMap을 사용할 수 있는 대규모 lib의 NonBlocking HashMap과 같은 항목을 반드시 확인해야 합니다.
java.util
명확한 답변으로 죄송하지만 대부분의 경우 기본 Java Collections로 충분합니다.
의 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★String
지도에서 http://code.google.com/p/flatmap를 보세요.
전 해피 컬렉션의 소스 위조 관련 해피 컬렉션 개발자입니다
- 이벤트 기반 컬렉션
- 수정할 수 없다
- 정렬 리스트
- 캐시
Concurrent Hash Map 및java.util.concurrent
여러 스레드에서 HashMap을 사용할 계획이라면 패키지에 대해 언급해야 합니다.이것은 표준 Java의 일부이기 때문에 메모리 용량이 작습니다.
"효율적"을 어떻게 정의하느냐에 따라 다릅니다.
모든 데이터 구조에는 읽기, 쓰기, 반복, 메모리 풋프린트 등의 빅오 동작이 있습니다.한 라이브러리의 링크 리스트는 다른 라이브러리와 동일합니다.또한 링크 리스트 O(n)보다 해시 맵이 O(1)를 읽는 속도가 빠릅니다.
하지만 내가 "가장 유용한 무료 자바 라이브러리?"라는 질문에 대한 답을 읽었을 때.나는 괴물이 거의 언급되지 않는다는 것을 알아차렸다.
이것은 "가장 효율적인" 것처럼 들리지 않습니다."가장 인기 있는" 것처럼 들리는데요.
피드백입니다. 들어본 적도 없고 사용해 본 사람도 없습니다.JDK, Google 또는 Apache Commons에 내장된 컬렉션은 잘 알고 있습니다.
Trove는 몇 가지 장점을 제공합니다.
- Map을 사용하지 않습니다.엔트리 오브젝트
- 맵의 키 대신 해시 전략을 사용할 수 있습니다.이것에 의해, 메모리가 절약되어 오브젝트를 그 속성의 새로운 세트에 캐시 할 때마다, 새로운 키를 정의할 필요가 없습니다.
- 그것은 원시적인 수집 유형을 가지고 있다
- 내부 반복기 같은 것이 있다고 생각한다
즉, trove가 작성된 이후 jdk 컬렉션을 개선하기 위해 많은 작업이 수행되었습니다.
해싱 전략 때문에 마음이 끌리긴 하지만...구글에서 검색하여 개요를 읽어보십시오.
해시 테이블에 수백만 개의 레코드를 저장할 경우 메모리 문제가 발생할 수 있습니다.예를 들어 230만 개의 String 객체가 있는 지도를 만들 때 이 일이 일어났습니다.저는 버클리 DB를 선택했는데, 매우 성숙하고 성능이 좋습니다.이들은 Collections API를 랩하는 Java API를 가지고 있기 때문에 메모리 설치 공간이 매우 적은 임의의 큰 맵을 쉽게 작성할 수 있습니다.다만, 디스크에 보존되어 있기 때문에, 액세스의 속도는 저하합니다.
후속 질문: 불변의 컬렉션을 위한 적절한(그리고 효율적인) 라이브러리가 있습니까?Clojure는 이를 매우 잘 지원하고 있으며, Java에도 비슷한 것이 있으면 좋겠습니다.
언급URL : https://stackoverflow.com/questions/629804/what-is-the-most-efficient-java-collections-library
'programing' 카테고리의 다른 글
JPA 매핑: "QuerySyntaxException: foobar가 매핑되지 않았습니다.." (0) | 2022.09.04 |
---|---|
cacerts와 keystore의 차이점은 무엇입니까? (0) | 2022.09.04 |
"SomeType@2f92e0f4"를 표시하지 않고 Java 객체를 인쇄하려면 어떻게 해야 합니까? (0) | 2022.09.04 |
Java의 UUID.randomUUID는 어느 정도 우수합니까? (0) | 2022.09.04 |
Spring Boot 2.5.0은 plain.jar 파일을 생성합니다.제거할 수 있나요? (0) | 2022.09.04 |