[java] 가장 효율적인 Java Collections 라이브러리는 무엇입니까? [닫은]

가장 효율적인 Java Collections 라이브러리는 무엇입니까?

몇 년 전, 나는 자바를 많이했고, 그때 인상을 가지고 발견 물이 최고 (가장 효율적인) 자바 컬렉션 구현입니다. 그러나 ” 가장 유용한 무료 Java 라이브러리? “라는 질문에 대한 답변을 읽었을 때 나는 그 말이 거의 언급되지 않았다는 것을 알았습니다 . 그렇다면 현재 가장 좋은 Java Collections 라이브러리는 무엇입니까?

업데이트 : 명확히하기 위해 해시 테이블 등에 수백만 개의 항목을 저장해야 할 때 사용하는 라이브러리를 알고 싶습니다 (작은 런타임 및 메모리 풋 프린트 필요).



답변

검사에서 Trove는 기본 유형의 컬렉션 라이브러리 일뿐입니다 .JDK의 일반 컬렉션보다 많은 기능을 추가하려는 것은 아닙니다.

개인적으로 (그리고 나는 편견입니다) 구아바 (구 구글 자바 컬렉션 프로젝트 포함 )를 좋아 합니다. 최소한 합리적으로 효율적인 방식으로 다양한 작업 (컬렉션 포함)을 훨씬 쉽게 만듭니다. 콜렉션 작업이 내 코드에서 병목 현상을 거의 일으키지 않는다는 것을 감안할 때 (내 경험상) 이것은 콜렉션 API보다 “더 나은”데, 이는 더 효율적일 수 있지만 코드를 읽을 수있는 것으로 만들지는 않습니다.

Trove와 Guava의 중복이 거의없는 경우 컬렉션 라이브러리에서 실제로 찾고있는 내용을 명확하게 설명 할 수 있습니다.


답변

문제는 (현재) 많은 데이터를 저장하는 것에 관한 것입니다.이 데이터는와 같은 기본 유형을 사용하여 나타낼 수 있습니다 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를 견딜 수있을 정도로 유용 합니다.


답변

나는 이것이 오래된 게시물이라는 것을 알고 있으며 여기에 많은 대답이 있습니다. 그러나 위의 답변은 도서관 제안 측면에서 피상적이고 단순합니다. 여기에 제시된 다양한 벤치 마크에서 잘 작동하는 라이브러리는 없습니다. 내가 얻는 유일한 결론은 성능과 메모리에 관심이 있고 특히 원시 유형을 다루는 경우 비 jdk 대안을 살펴볼 가치가 있다는 것입니다.

다음은 벤치 마크 역학 및 해당 라이브러리와 관련하여보다 건전한 분석입니다.
이것은 mahout dev 목록의 스레드입니다.

다루는 도서관은

  • HPPC
  • 트 로브
  • FastUtil
  • 마 흐트 (콜트)
  • 자바 컬렉션

2015 년 6 월 업데이트 : 불행히도 원래 벤치 마크는 더 이상 사용할 수 없으며 약간 오래된 것입니다.
다음 은 다른 사람이 수행 한 상당히 최근 (2015 년 1 월) 벤치 마크입니다. 그것은 포괄적이 아니며 대화 형 탐색 도구를 원본 링크만큼 가지고 있지 않습니다.


답변

다른 논평가들이 알듯이, “효율적인”의 정의는 넓은 그물을 던진다. 그러나 아직 아무도 Javolution 라이브러리를 언급하지 않았습니다 .

일부 하이라이트 :

  • Javolution 클래스는 빠르고 매우 빠릅니다 (예 : 표준 StringBuffer / StringBuilder의 경우 O [n] 대신 O [Log (n)]의 텍스트 삽입 / 삭제).
  • 모든 Javolution 클래스는 실시간에 적합하지 않으며 결정적인 동작 (마이크로 초 범위)을 갖습니다. 또한 표준 라이브러리와 달리 Javolution은 RTSJ 안전합니다 (Java Real-Time 확장과 함께 사용할 경우 메모리 충돌 또는 메모리 누수 없음).
  • Javolution의 실시간 컬렉션 클래스 (맵, 목록, 테이블 및 세트)는 대부분의 표준 컬렉션 클래스 대신 사용할 수 있으며 추가 기능을 제공합니다.
  • Javolution 컬렉션은 동시성 보장을 제공하여 병렬 알고리즘을보다 쉽게 ​​구현할 수 있습니다.

Javolution 배포판에는 벤치 마크 모음이 포함되어있어 다른 라이브러리 / 내장 모음과 비교하여 어떻게 누적되는지 확인할 수 있습니다.


답변

고려해야 할 일부 콜렉션 라이브러리 :

우선 JDK 콜렉션 라이브러리에 도달했습니다. 그것은 당신이해야 할 가장 일반적인 일을 다루고 있으며 분명히 당신에게 이미 사용 가능합니다.

Google 컬렉션은 아마도 JDK 외부의 최고의 고품질 라이브러리 일 것입니다. 많이 사용되고 잘 지원됩니다.

Apache Commons Collections는 오래되었으며 “너무 많은 요리사”문제로 인해 어려움을 겪지 만 유용한 정보가 많이 있습니다.

Trove는 프리미티브 키 / 값과 같은 경우를 위해 매우 전문화 된 컬렉션을 보유하고 있습니다. 요즘 우리는 현대 JDK와 Java 5+ 컬렉션 및 동시 사용 사례에서 JDK 컬렉션이 특수한 Trove 컬렉션보다 성능이 뛰어납니다.

동시성 사용 사례가 실제로 높은 경우, 고급 라이브러리에서 NonBlockingHashMap과 같은 항목을 확인해야합니다. 이는 잠금이없는 구현이며 올바른 사용 사례가 있으면 ConcurrentHashMap에서 스톰 핑 할 수 있습니다.


답변

java.util

분명한 대답은 유감이지만 대부분의 경우 기본 Java 콜렉션 으로 충분합니다.


답변

수백만의 String지도를지도에 저장하려면 http://code.google.com/p/flatmap 을 참조 하십시오.